diff --git a/lisp/crosshairs.el b/lisp/crosshairs.el
new file mode 100755
index 0000000..bec0790
--- /dev/null
+++ b/lisp/crosshairs.el
@@ -0,0 +1,1303 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; BEGIN modification of the Multiple Cursors library written by  Magnar Sveen.
+
+(defvar package-archives)
+
+(defvar mc--max-cursors-original)
+(defvar mc/max-cursors)
+(defvar mc--max-cursors-original)
+(defvar mc/max-cursors)
+(defvar mc/always-run-for-all)
+(defvar mc--this-command)
+(defvar mc/cmds-to-run-once)
+(defvar mc--default-cmds-to-run-for-all)
+(defvar mc/cmds-to-run-for-all)
+(defvar mc--default-cmds-to-run-once)
+(defvar mc--executing-command-for-fake-cursor)
+
+(declare-function mc/make-cursor-overlay-at-point "ext:multiple-cursors-core")
+(declare-function multiple-cursors-mode "ext:multiple-cursors-core")
+(declare-function mc/num-cursors "ext:multiple-cursors-core")
+(declare-function mc/remove-fake-cursors "ext:multiple-cursors-core")
+(declare-function mc/create-cursor-id "ext:multiple-cursors-core")
+(declare-function mc/store-current-state-in-overlay "ext:multiple-cursors-core")
+(declare-function mc/make-region-overlay-between-point-and-mark "ext:multiple-cursors-core")
+(declare-function mc/execute-command-for-all-fake-cursors "ext:multiple-cursors-core")
+(declare-function mc/prompt-for-inclusion-in-whitelist "ext:multiple-cursors-core")
+(declare-function mc/all-fake-cursors "ext:multiple-cursors-core")
+(declare-function mc/mark-next-like-this "ext:mc-mark-more")
+(declare-function mc/mark-previous-like-this  "ext:mc-mark-more")
+
+;;;###autoload
+(defun mc/built-in-cursors ()
+"Load the modifications that enable the multiple-cursors package (Magnar Sveen)
+to take advantage of the built-in fake cursors."
+
+  (define-key global-map [S-mouse-1] 'mc/add-cursor-on-click)
+  (define-key global-map [?\M-d] 'mc/mark-next-like-this-cycle-forward)
+  (define-key global-map [?\M-D] 'mc/mark-previous-like-this-cycle-forward)
+  (define-key global-map [?\s-d] 'mc/mark-next-like-this-cycle-forward)
+  (define-key global-map [?\s-D] 'mc/mark-previous-like-this-cycle-forward)
+  (define-key global-map (kbd "<C-s-268632071>") 'mc/mark-all-like-this)
+  (define-key global-map (kbd "C-s-g") 'mc/mark-all-like-this)
+  (define-key global-map (kbd "S-s-d") 'mc/mark-previous-like-this-cycle-forward)
+  (define-key global-map (kbd "C-l") 'mc/edit-ends-of-lines)
+  (define-key global-map (kbd "C-S-l") 'mc/edit-beginnings-of-lines)
+
+  (add-hook 'multiple-cursors-mode-disabled-hook
+            (lambda () (kill-local-variable 'multiple-cursors-conf)))
+
+  (defvar mc/use-built-in-cursors t
+  "Whether to use the built-in fake cursors.")
+
+  (defun mc/create-fake-cursor-at-point (&optional id)
+    "Add a fake cursor and possibly a fake active region overlay based on point and mark.
+  Saves the current state in the overlay to be restored later."
+    (unless mc--max-cursors-original
+      (setq mc--max-cursors-original mc/max-cursors))
+    (when mc/max-cursors
+      (unless (< (mc/num-cursors) mc/max-cursors)
+        (if (yes-or-no-p (format "%d active cursors. Continue? " (mc/num-cursors)))
+            (setq mc/max-cursors (read-number "Enter a new, temporary maximum: "))
+          (mc/remove-fake-cursors)
+          (error "Aborted: too many cursors"))))
+    (let ((overlay
+            (if mc/use-built-in-cursors
+              (make-overlay (point) (point))
+              (mc/make-cursor-overlay-at-point))))
+      (overlay-put overlay 'mc-id (or id (mc/create-cursor-id)))
+      (overlay-put overlay 'type 'fake-cursor)
+      (overlay-put overlay 'priority 100)
+      (mc/store-current-state-in-overlay overlay)
+      (when (use-region-p)
+        (overlay-put overlay 'region-overlay
+                     (mc/make-region-overlay-between-point-and-mark)))
+      overlay))
+
+  (defun mc/execute-this-command-for-all-cursors-1 ()
+    "Used with post-command-hook to execute supported commands for all cursors.
+  -  It uses two lists of commands to know what to do: the run-once
+  list and the run-for-all list. If a command is in neither of these lists,
+  it will prompt for the proper action and then save that preference.
+  -  Some commands are so unsupported that they are even prevented for
+  the original cursor, to inform about the lack of support."
+    (unless mc--executing-command-for-fake-cursor
+      (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc-mode
+          (multiple-cursors-mode 0)
+        (when this-original-command
+          (let ((original-command (or mc--this-command
+                                      (command-remapping this-original-command)
+                                      this-original-command)))
+            ;; skip keyboard macros, since they will generate actual commands that are
+            ;; also run in the command loop - we'll handle those later instead.
+            (when (functionp original-command)
+              ;; if it's a lambda, we can't know if it's supported or not
+              ;; - so go ahead and assume it's ok, because we're just optimistic like that
+              (if (or (not (symbolp original-command))
+                      ;; lambda registered by smartrep
+                      (string-prefix-p "(" (symbol-name original-command)))
+                  (mc/execute-command-for-all-fake-cursors original-command)
+                ;; smartrep `intern's commands into own obarray to help
+                ;; `describe-bindings'.  So, let's re-`intern' here to
+                ;; make the command comparable by `eq'.
+                (setq original-command (intern (symbol-name original-command)))
+                ;; otherwise it's a symbol, and we can be more thorough
+                (if (get original-command 'mc--unsupported)
+                    (message "%S is not supported with multiple cursors%s"
+                             original-command
+                             (get original-command 'mc--unsupported))
+                  (when (and original-command
+                             (not (memq original-command mc--default-cmds-to-run-once))
+                             (not (memq original-command mc/cmds-to-run-once))
+                             (or mc/always-run-for-all
+                                 (memq original-command mc--default-cmds-to-run-for-all)
+                                 (memq original-command mc/cmds-to-run-for-all)
+                                 (mc/prompt-for-inclusion-in-whitelist original-command)))
+                    (mc/execute-command-for-all-fake-cursors original-command))))
+              (when mc/use-built-in-cursors
+                (setq multiple-cursors-conf
+                        (mapcar
+                          (lambda (x) (list (overlay-start x) "bar" nil))
+                          (mc/all-fake-cursors))))))))))
+
+  (defun mc/mark-next-like-this-cycle-forward ()
+  "Marks next occurence of word like this and advances cursor to this occurrence"
+  (interactive)
+    (mc/mark-next-like-this 1))
+
+  (defun mc/mark-previous-like-this-cycle-forward ()
+  "Marks next occurrence of word like this and advances cursor to this occurrence"
+  (interactive)
+    (mc/mark-previous-like-this 1))
+
+  (add-to-list 'mc--default-cmds-to-run-once 'mc/mark-next-like-this-cycle-forward)
+
+  (add-to-list 'mc--default-cmds-to-run-once 'mc/mark-previous-like-this-cycle-forward))
+
+(eval-after-load "multiple-cursors-core"
+  '(progn
+     (mc/built-in-cursors)))
+
+;;;###autoload
+(defun mc-install ()
+"To use multiple-cursors after restarting Emacs, make sure that the following line
+appears somewhere in the .emacs/init.el:  (package-initialize)"
+(interactive)
+  (require 'package)
+  (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
+  (package-initialize)
+  (package-refresh-contents)
+  (if (locate-library "multiple-cursors-core")
+    (unless (featurep 'multiple-cursors-core)
+      (require 'multiple-cursors-core))
+    (package-install 'multiple-cursors))
+  (mc/built-in-cursors))
+
+;;; END modification of the Multiple Cursors library written by  Magnar Sveen.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; BEGIN crosshairs.el
+
+;;; BUILT-IN VARIABLES:
+
+;;; The variables `crosshairs-horizontal-ruler' and `crosshairs-vertical-ruler'
+;;; may be used to suppress either or both of the rulers that create crosshairs.
+;;;
+;;; (setq crosshairs-horizontal-ruler nil)
+;;;
+;;; (setq crosshairs-vertical-ruler nil)
+
+;;; The variable `mc-real-fake-cursor' controls what type of cursor will
+;;; be drawn in lieu of the real cursor when crosshairs are active.  The string
+;;; "no" will cause the creation of a horizontal and vertical bar for a seamless
+;;; appearance.
+;;;
+;;; (setq mc-real-fake-cursor "no")
+
+;;; When `crosshairs-draw-forthwith' is non-nil, draw crosshairs whenever the
+;;; real cursor would ordinarily be drawn, which is sometimes more than once
+;;; every command loop.  When `crosshairs-draw-forthwith' is nil, crosshairs
+;;; will be placed on an idle-timer.  If this variable is reset while `+-mode'
+;;; is enabled, then it may be necessary to turn off/on `+-mode' to reset
+;;; functions attached to the `post-command-hook'.  The default is nil.
+;;;
+;;; (setq crosshairs-draw-forthwith t)
+
+;;; The variables `multiple-cursors-inactive-windows' and `crosshairs-inactive-windows'
+;;; may be used to display multiple cursors and/or crosshairs in the inactive
+;;; windows.  The default is non-nil.  A non-nil value will turn on this feature.
+;;;
+;;; (setq multiple-cursors-inactive-windows nil)
+;;;
+;;; (setq crosshairs-inactive-windows nil)
+
+;;; When `multiple-cursors-draw-forthwith' is non-nil, draw crosshairs whenever the
+;;; real cursor would ordinarily be drawn, which is sometimes more than once
+;;; every command loop.  When `multiple-cursors-draw-forthwith' is nil, crosshairs
+;;; will be placed on an idle-timer.  If this variable is reset while `multiple-cursors-mode'
+;;; is enabled, then it may be necessary to turn off/on `multiple-cursors-mode' to reset
+;;; functions attached to the `post-command-hook'.  The default is non-nil.
+;;;
+;;; (setq multiple-cursors-draw-forthwith nil)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; FACES
+
+(defgroup +-mode nil
+  "Faces for the vertical ruler."
+  :group 'convenience)
+
+(defface +-form-feed-face
+  (cond
+    ((eq system-type 'darwin)
+      '((t (:foreground "magenta"))))
+    ((eq system-type 'windows-nt)
+      '((t (:foreground "magenta")))))
+  "Face for `+-form-feed-face'."
+  :group '+-mode)
+
+(defface +-newline-face
+  '((t (:foreground "#555555")))
+  "Face for `+-newline-face'."
+  :group '+-mode)
+
+(defface +-space-face
+  '((t (:foreground "DarkRed")))
+  "Face for `+-space-face'."
+  :group '+-mode)
+
+(defface +-tab-face
+  '((t (:foreground "cyan")))
+  "Face for `+-tab-face'."
+  :group '+-mode)
+
+(defface +-tab-spacer-face
+  '((t (:background "grey25")))
+  "Face for `+-tab-spacer-face'."
+  :group '+-mode)
+
+(defface +-left-fringe-current-line-face
+  '((t (:foreground "green")))
+  "Face for `+-left-fringe-current-line-face'."
+  :group '+-mode)
+
+(defface +-left-fringe-cursor-alt-one-face
+  '((t (:foreground "blue")))
+  "Face for `+-left-fringe-cursor-alt-one-face'."
+  :group '+-mode)
+
+(defface +-left-fringe-cursor-alt-two-face
+  '((t (:foreground "red")))
+  "Face for `+-left-fringe-cursor-alt-two-face'."
+  :group '+-mode)
+
+(defface +-hollow-rectangle-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-hollow-rectangle-face'."
+  :group '+-mode)
+
+(defface +-backslash-face
+  '((t (:foreground "grey25")))
+  "Face for `+-backslash-face'."
+  :group '+-mode)
+
+(defface +-fringe-question-mark-face
+  '((t (:foreground "green")))
+  "Face for `+-fringe-question-mark-face'."
+  :group '+-mode)
+
+(defface +-fringe-exclamation-mark-face
+  '((t (:foreground "cyan")))
+  "Face for `+-fringe-exclamation-mark-face'."
+  :group '+-mode)
+
+(defface +-fringe-left-arrow-face
+  '((t (:foreground "purple")))
+  "Face for `+-fringe-left-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-right-arrow-face
+  '((t (:foreground "OrangeRed")))
+  "Face for `+-fringe-right-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-up-arrow-face
+  '((t (:foreground "RoyalBlue")))
+  "Face for `+-fringe-up-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-down-arrow-face
+  '((t (:foreground "cyan")))
+  "Face for `+-fringe-down-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-left-curly-arrow-face
+  '((t (:foreground "grey25")))
+  "Face for `+-fringe-left-curly-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-right-curly-arrow-face
+  '((t (:foreground "#3c3c3c")))
+  "Face for `+-fringe-right-curly-arrow-face'."
+  :group '+-mode)
+
+(defface +-fringe-left-triangle-face
+  '((t (:foreground "red")))
+  "Face for `+-fringe-left-triangle-face'."
+  :group '+-mode)
+
+(defface +-fringe-right-triangle-face
+  '((t (:foreground "yellow")))
+  "Face for `+-fringe-right-triangle-face'."
+  :group '+-mode)
+
+(defface +-fringe-top-left-angle-face
+  '((t (:foreground "magenta")))
+  "Face for `+-fringe-top-left-angle-face'."
+  :group '+-mode)
+
+(defface +-fringe-top-right-angle-face
+  '((t (:foreground "orange")))
+  "Face for `+-fringe-top-right-angle-face'."
+  :group '+-mode)
+
+(defface +-fringe-bottom-left-angle-face
+  '((t (:foreground "magenta")))
+  "Face for `+-fringe-bottom-left-angle-face'."
+  :group '+-mode)
+
+(defface +-fringe-bottom-right-angle-face
+  '((t (:foreground "magenta")))
+  "Face for `+-fringe-bottom-right-angle-face'."
+  :group '+-mode)
+
+(defface +-fringe-left-bracket-face
+  '((t (:foreground "yellow")))
+  "Face for `+-fringe-left-bracket-face'."
+  :group '+-mode)
+
+(defface +-fringe-right-bracket-face
+  '((t (:foreground "green")))
+  "Face for `+-fringe-right-bracket-face'."
+  :group '+-mode)
+
+(defface +-fringe-filled-rectangle-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-fringe-filled-rectangle-face'."
+  :group '+-mode)
+
+(defface +-fringe-hollow-square-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-fringe-hollow-square-face'."
+  :group '+-mode)
+
+(defface +-fringe-filled-square-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-fringe-filled-square-face'."
+  :group '+-mode)
+
+(defface +-fringe-horizontal-bar-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-fringe-horizontal-bar-face'."
+  :group '+-mode)
+
+(defface +-fringe-empty-line-face
+  '((t (:foreground "DarkGreen")))
+  "Face for `+-fringe-empty-line-face'."
+  :group '+-mode)
+
+(defface +-parens-one-face
+  '((t (:foreground "magenta")))
+  "Face for `+-parens-one-face'."
+  :group '+-mode)
+
+(defface +-parens-two-face
+  '((t (:foreground "red")))
+  "Face for `+-parens-two-face'."
+  :group '+-mode)
+
+(defface +-parens-three-face
+  '((t (:foreground "yellow")))
+  "Face for `+-parens-three-face'."
+  :group '+-mode)
+
+(defface +-parens-four-face
+  '((t (:foreground "green")))
+  "Face for `+-parens-four-face'."
+  :group '+-mode)
+
+(defface +-parens-five-face
+  '((t (:foreground "cyan")))
+  "Face for `+-parens-five-face'."
+  :group '+-mode)
+
+(defface +-parens-six-face
+  '((t (:foreground "orange")))
+  "Face for `+-parens-six-face'."
+  :group '+-mode)
+
+(defface +-parens-seven-face
+  '((t (:foreground "purple")))
+  "Face for `+-parens-seven-face'."
+  :group '+-mode)
+
+(defface +-parens-eight-face
+  '((t (:foreground "blue")))
+  "Face for `+-parens-eight-face'."
+  :group '+-mode)
+
+(defface +-parens-nine-face
+  '((t (:foreground "brown")))
+  "Face for `+-parens-nine-face'."
+  :group '+-mode)
+
+(defface +-parens-ten-face
+  '((t (:foreground "white")))
+  "Face for `+-parens-ten-face'."
+  :group '+-mode)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; VARIABLES
+
+(defvar +-mode)
+
+(defvar +-fill-column t
+"When non-nil, display a visible fill column indicator.  If `mc-fill-column-mode'
+is activate when `+-mode' is turned on, the former will be turned off.")
+
+(defvar +-buffer-display-table
+  (let* ((ff-char ?\u0046)
+         (display-table (make-display-table))
+         (glyph-form-feed (make-glyph-code ff-char '+-form-feed-face))
+         (glyph-pilcrow (make-glyph-code ?\u00B6 '+-newline-face))
+         (glyph-space (make-glyph-code ?\u00B7 '+-space-face))
+         (glyph-tab (make-glyph-code ?\u00BB '+-tab-face))
+         (glyph-tab-spacer (make-glyph-code ?\t '+-tab-spacer-face)))
+    (aset display-table ?\n `[,glyph-pilcrow ?\n])
+    (aset display-table ?\f `[,glyph-form-feed ,glyph-form-feed])
+    ;;; minimum tab-width is `2`
+    ;; (aset display-table ?\t `[,glyph-tab ?\t])
+    (aset display-table ?\t `[,glyph-tab ,glyph-tab-spacer])
+    ;;; tab-width always equals `1`
+    ;; (aset display-table ?\t `[,glyph-tab])
+    (aset display-table ?\s `[,glyph-space])
+    display-table)
+  "The `buffer-display-table' that is used when `+-mode' is active.")
+
+(defvar +-timer-var nil
+"Timer used to highlight current column whenever Emacs is idle.")
+
+(defvar +-idle-timer-seconds 0.5
+  "The number of seconds to delay before drawing crosshairs when the variable
+`crosshairs-draw-forthwith' has a nil value.")
+
+(defvar +-truncate-lines-major-modes '()
+  "List of major modes were truncate lines shall be enabled.")
+
+(defvar +-truncate-lines-derived-modes '(prog-mode)
+  "List of derived modes were truncate lines shall be enabled.")
+
+(defvar +--saved-state nil
+  "Used to store/restore certain buffer-local variables when enabling/disabling)
+`+-mode'.")
+
+(defvar +-parens-inactive-windows t
+  "When non-nil, display matching parentheses in the inactive window.")
+(make-variable-buffer-local '+-parens-inactive-windows)
+
+(defvar +-parens-exclusions '(mwheel-scroll)
+  "List of functions that will prevent matching parentheses from updating.")
+
+(defvar +-parens-from-fn nil
+  "Custom function to determine how far back towards the beginning of the file
+should `+-parens-fn' search for matching parentheses -- the result thrown from
+this custom function must be a buffer point.  If no custom function is defined,
+then `+-parens-fn' will use `point-min'.")
+
+(defvar +-parens-overlays-exist-p nil
+"Simple test to see whether the parens overlays have been placed.
+This could be a different kind of test -- e.g., scanning for the
+presence of specific overlays, but perhaps that is overkill.")
+(make-variable-buffer-local '+-parens-overlays-exist-p)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; FUNCTIONS
+
+;;;###autoload
+(defun mc-test ()
+"Draw fake cursors at all POS defined in the `multiple-cursors-conf'.  Multiple fake cursors
+are supported by GUI versions of Emacs built for X, Windows and OSX.
+Popular forms of specifying colors such as \"red\" and \"#FF0000\" are now
+supported, as well as LSL color vectors such as [1.0 0.0 0.0].  For those users
+who choose the former familiar methods of specifying colors with strings,
+`mc_color_vector_calculate' will convert those strings to LSL color vectors.
+The color vectors are commonly referred to as LSL (The Linden Scripting Language).
+`nsterm.m' uses `NSColor', which works well with LSL.  `w32term.c' uses
+`PALETTERGB' or `RGB', and the conversion from LSL is done internally by
+multiplying each element of the LSL color vector by 255.  `xterm.c' uses
+`x_make_truecolor_pixel', which uses 16-bit RGB -- the conversion from LSL
+happens internally by multiplying each element of the LSL color vector by 65535."
+(interactive)
+  (let ((buffer (get-buffer-create "*MC-TEST*")))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (insert "This is a test!")
+      (setq multiple-cursors-conf '((1 "hbar" "magenta")
+                                    (2 "bar" "purple")
+                                    (3 "box" "#00FF00")
+                                    (4 "hollow" "#0000FF")
+                                    (5 ("hbar" 3) [1.0 0.0 1.0])
+                                    (6 ("bar" 3) [0.0 1.0 1.0]))))
+    (select-window (display-buffer buffer))
+    ;;; The trigger in `keyboard.c` is not activated in this example, so we
+    ;;; force the multiple cursors to be drawn.
+    (mc-activate-multiple-cursors (selected-window))))
+
+(defun +-timer-fn ()
+"Since this fires globally, we must control which buffers crosshairs appear in."
+  (when +-mode
+    (unless (memq last-command +-parens-exclusions)
+      (+-parens-fn))
+    (when +-timer-var
+      (setq timer-idle-list (delq +-timer-var timer-idle-list))
+      (setq +-timer-var nil))
+    (unless crosshairs-draw-forthwith
+      (mc-activate-crosshairs (selected-window)))
+    (when (and +-fill-column (null mc-fill-column-draw-forthwith))
+      (mc-activate-fill-column (selected-window)))))
+
+(defun +-draw-forthwith ()
+  "Force both rulers to be drawn/redrawn."
+  (+-draw-crosshairs 'force))
+
+(defun +-draw-crosshairs (&optional force)
+  (when +-mode
+    (when +-timer-var
+      (setq timer-idle-list (delq +-timer-var timer-idle-list))
+      (setq +-timer-var nil))
+    (unless (memq this-command +-parens-exclusions)
+      (+-delete-parens-overlays))
+    (if force
+      (progn
+        (+-parens-fn)
+        (unless crosshairs-draw-forthwith
+          (mc-activate-crosshairs (selected-window)))
+        (when (and +-fill-column (null mc-fill-column-draw-forthwith))
+          (mc-activate-fill-column (selected-window))))
+      (setq +-timer-var (run-with-idle-timer +-idle-timer-seconds nil #'+-timer-fn)))))
+
+;;;###autoload
+(define-minor-mode +-mode
+"Minor mode for displaying a horizontal ruler."
+  :init-value nil
+  :lighter " +"
+  :keymap nil
+  :global nil
+  :group '+-mode
+  (cond
+    (+-mode
+      ;;; `+-mode' has the ability to also display a fill column indicator.
+      ;;; See the variable `+-fill-column'.
+      (when mc-fill-column-mode
+        (mc-fill-column-mode -1))
+      (when (and global-eldoc-mode
+                 (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (global-eldoc-mode -1))
+      (when (and jit-lock-context-timer
+                 (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (when (timerp jit-lock-context-timer)
+          (cancel-timer jit-lock-context-timer))
+        ;; (setq jit-lock-context-timer (run-with-idle-timer 5.0 'repeat 'jit-lock-context-fontify))
+        (setq jit-lock-context-timer nil))
+      (when (and (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (when (timerp undo-auto-current-boundary-timer)
+          (cancel-timer undo-auto-current-boundary-timer))
+        (fset 'undo-auto--undoable-change
+              (lambda () (add-to-list 'undo-auto--undoably-changed-buffers (current-buffer))))
+        (fset 'undo-auto-amalgamate 'ignore))
+      (when blink-cursor-mode
+        (blink-cursor-mode -1)
+        (when (memq 'blink-cursor-check post-command-hook)
+          (remove-hook 'post-command-hook 'blink-cursor-check)))
+      (when (and (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4))
+                 (null crosshairs-draw-forthwith))
+        (setq crosshairs-draw-forthwith t))
+      (setq crosshairs t)
+      (when +-fill-column
+        (setq mc-fill-column t))
+      ;;; `auto-composition-mode' is needed for crosshairs to properly calculate
+      ;;; coordinates of composition characters.  Automatically becomes permanently
+      ;;; buffer-local when set.
+      (unless auto-composition-mode
+        (setq auto-composition-mode t))
+      ;;; @lawlist is focusing the initial development of feature requests #17684
+      ;;; and #22873 on L2R languages.  The feature test file used by @lawlist
+      ;;; bogs Emacs down unless `bidi-display-reordering' is set to a nil value.
+      ;;; However, most users will probably not want this particular setting.
+      (unless (null bidi-display-reordering)
+        (setq bidi-display-reordering nil))
+      (unless (and (called-interactively-p 'any)
+                   (equal current-prefix-arg '(4)))
+        (set (make-local-variable '+--saved-state) nil)
+        (dolist (var '(buffer-display-table
+                       fringe-indicator-alist
+                       tab-width
+                       line-move-visual
+                       truncate-lines
+                       truncate-partial-width-windows
+                       word-wrap))
+          (when (local-variable-p var)
+            (push (cons var (symbol-value var)) +--saved-state)))
+        (setq fill-column 80)
+        (setq display-line-numbers t)
+        (setq-local auto-hscroll-mode 'current-line)
+        (setq-local hscroll-step 5)
+        (setq buffer-display-table +-buffer-display-table)
+        (setq tab-width 4)
+        (set (make-local-variable 'line-move-visual) t)
+        (setq truncate-lines
+          (cond
+            ((let ((lst +-truncate-lines-derived-modes)
+                    mode)
+              (catch 'found
+                (while (setq mode (pop lst))
+                  (when (derived-mode-p mode)
+                    (throw 'found t))))))
+             ((memq major-mode +-truncate-lines-major-modes))
+             (t
+               nil)))
+        (set (make-local-variable 'truncate-partial-width-windows) nil)
+        (setq word-wrap t)
+        (setq indicate-empty-lines t)
+        (setq indicate-buffer-boundaries 'left)
+        (setq fringe-indicator-alist
+            ;;; hscl_all_temp_p | hscl_temp_p
+          '((+-hscl-temp . (+-single-angle-left
+                            +-double-angle-left))
+            ;;; hscl_all_perm_0_p | hscl_all_perm_1_p | hscl_all_perm_2_p | hscl_perm_p
+            (+-hscl-perm . (+-single-angle-up
+                            +-double-angle-up
+                            +-triple-angle-up
+                            +-quadruple-angle-up))
+            (+-overlay-arrow . (+-fringe-left-arrow
+                                +-fringe-right-arrow))
+            (truncation . (+-fringe-left-arrow
+                           +-fringe-right-arrow))
+            (continuation . (+-fringe-left-curly-arrow
+                             +-backslash))
+            (overlay-arrow . +-fringe-right-triangle)
+            (up . +-fringe-up-arrow)
+            (down . +-fringe-down-arrow)
+            (top . +-fringe-top-left-angle)
+            (bottom . +-fringe-bottom-right-angle)
+            (top-bottom . (+-fringe-left-bracket
+                           +-fringe-right-bracket
+                           +-fringe-top-right-angle
+                           +-fringe-top-left-angle))
+            (empty-line . +-fringe-empty-line)
+            (unknown . +-fringe-question-mark)))
+        (setq fringe-cursor-alist '((box . +-fringe-left-triangle)
+                                    (hollow . +-hollow-rectangle)
+                                    (bar . +-vertical-bar)
+                                    (hbar . +-fringe-horizontal-bar)
+                                    (hollow-small . +-fringe-hollow-square)))
+        (if crosshairs-draw-forthwith
+          (add-hook 'post-command-hook '+-draw-forthwith 'append 'local)
+          (add-hook 'post-command-hook '+-draw-crosshairs 'append 'local))
+        (when crosshairs-draw-forthwith
+          (add-hook 'window-configuration-change-hook '+-draw-forthwith nil 'local))
+        (add-hook 'change-major-mode-hook 'turn-off-+-mode nil 'local))
+      (when (called-interactively-p 'any)
+        (if (equal current-prefix-arg '(4))
+          (message "Turned ON `+-mode' -- debugging mode.")
+          (message "Turned ON `+-mode'."))))
+    (t
+      (kill-local-variable 'fill-column)
+      (kill-local-variable 'auto-hscroll-mode)
+      (kill-local-variable 'hscroll-step)
+      (kill-local-variable 'crosshairs)
+      (kill-local-variable 'mc-fill-column)
+      (kill-local-variable 'display-line-numbers)
+      (kill-local-variable 'display-line-numbers-width)
+      (kill-local-variable 'multiple-cursors-conf)
+      (kill-local-variable 'buffer-display-table)
+      (kill-local-variable 'tab-width)
+      (kill-local-variable 'line-move-visual)
+      (kill-local-variable 'truncate-lines)
+      (kill-local-variable 'truncate-partial-width-windows)
+      (kill-local-variable 'word-wrap)
+      (kill-local-variable 'indicate-empty-lines)
+      (kill-local-variable 'indicate-buffer-boundaries)
+      (kill-local-variable 'fringe-indicator-alist)
+      (kill-local-variable 'fringe-cursor-alist)
+      (dolist (saved +--saved-state)
+        (set (make-local-variable (car saved)) (cdr saved)))
+      (kill-local-variable '+--saved-state)
+      (+-delete-parens-overlays)
+      (when (memq '+-draw-forthwith post-command-hook)
+        (remove-hook 'post-command-hook '+-draw-forthwith 'local))
+      (when (memq '+-draw-crosshairs post-command-hook)
+        (remove-hook 'post-command-hook '+-draw-crosshairs 'local))
+      (when (memq '+-draw-forthwith window-configuration-change-hook)
+        (remove-hook 'window-configuration-change-hook '+-draw-forthwith 'local))
+      (remove-hook 'change-major-mode-hook 'turn-off-+-mode 'local)
+      (when +-timer-var
+        (setq timer-idle-list (delq +-timer-var timer-idle-list))
+        (setq +-timer-var nil))
+      (when (called-interactively-p 'any)
+        (message "Turned OFF `+-mode'.")))))
+
+(defun turn-off-+-mode ()
+  (+-mode -1))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun +-parens-fn ()
+  "Doc-string."
+  (let* ((opoint (point))
+         (from (if +-parens-from-fn
+                 (funcall +-parens-from-fn)
+                 (point-min)))
+         (win (selected-window))
+         (i 0)
+         (preceding-char (preceding-char))
+         (ochar (char-after opoint))
+         (pos1
+           (cond
+             ((and ochar
+                   (or ;;; (char-to-string 40) => opening parenthesis
+                       (= ochar 40)
+                       ;;; (char-to-string 91) => opening square bracket
+                       (= ochar 91)
+                       ;;; (char-to-string 123) => opening wavy bracket
+                       (= ochar 123)))
+                (min (1+ opoint) (point-max)))
+             ((or ;;; (char-to-string 41) => closing parenthesis
+                  (= preceding-char 41)
+                  ;;; (char-to-string 93) => closing square bracket
+                  (= preceding-char 93)
+                  ;;; (char-to-string 125) => closing wavy bracket
+                  (= preceding-char 125))
+                (max (point-min) (1- opoint)))
+             (t
+                opoint)))
+         pos2
+         selected-face)
+    (save-excursion
+      (condition-case nil
+        (while (setq pos1 (nth 1 (parse-partial-sexp from pos1)))
+          (setq pos2 (scan-sexps pos1 1))
+          (if (= i 10)
+            (setq i 1)
+            (setq i (1+ i)))
+          (setq selected-face (cond
+                                ((= i 1)
+                                  '+-parens-one-face)
+                                ((= i 2)
+                                  '+-parens-two-face)
+                                ((= i 3)
+                                  '+-parens-three-face)
+                                ((= i 4)
+                                  '+-parens-four-face)
+                                ((= i 5)
+                                  '+-parens-five-face)
+                                ((= i 6)
+                                  '+-parens-six-face)
+                                ((= i 7)
+                                  '+-parens-seven-face)
+                                ((= i 8)
+                                  '+-parens-eight-face)
+                                ((= i 9)
+                                  '+-parens-nine-face)
+                                ((= i 10)
+                                  '+-parens-ten-face)))
+          (let ((ov (make-overlay pos1 (1+ pos1))))
+            (unless +-parens-inactive-windows
+              (overlay-put ov 'window win))
+            (overlay-put ov 'face selected-face))
+          (when pos2
+            (let ((ov (make-overlay (1- pos2) pos2)))
+              (unless +-parens-inactive-windows
+                (overlay-put ov 'window win))
+              (overlay-put ov 'face selected-face))))
+        (error nil)))
+    (setq +-parens-overlays-exist-p t)))
+
+(defun +-remove-overlays (beg end name val)
+"Remove the overlays that are `equal-including-properties`.
+Includes a unique situation when an overlay with an `'after-string` property
+is at the very end of a narrowed-buffer."
+  (let* ((point-max (point-max))
+         (point-min (point-min))
+         (narrowed-p (buffer-narrowed-p))
+         (beg (if beg beg point-min))
+         (end
+           (cond
+             ((and
+                 (not narrowed-p)
+                 end)
+               end)
+             ((and
+                 (not narrowed-p)
+                 (null end))
+               point-max)
+             ((and
+                 narrowed-p
+                 end
+                 (< end point-max))
+               end)
+             ((and
+                 narrowed-p
+                 end
+                 (= end point-max))
+               (1+ end))
+             ((and
+                 narrowed-p
+                 (null end))
+               (1+ point-max)) ))
+         (overlays
+           (progn
+             (overlay-recenter end)
+             (overlays-in beg end))))
+    (when (and beg end name val)
+      (dolist (o overlays)
+        (cond
+          ((and (eq name 'face)
+                (eq (overlay-get o name) val))
+            ;; Either push this overlay outside beg...end
+            ;; or split it to exclude beg...end
+            ;; or delete it entirely (if it is contained in beg...end).
+            (if (< (overlay-start o) beg)
+                (if (> (overlay-end o) end)
+              (progn
+                (move-overlay (copy-overlay o)
+                  (overlay-start o) beg)
+                (move-overlay o end (overlay-end o)))
+                  (move-overlay o (overlay-start o) beg))
+              (if (> (overlay-end o) end)
+                  (move-overlay o end (overlay-end o))
+                (delete-overlay o))))
+          ((and (not (eq name 'face))
+                (equal-including-properties (overlay-get o name) val))
+            (delete-overlay o)))))))
+
+(defun +-delete-parens-overlays ()
+  (when +-parens-overlays-exist-p
+    (dolist (face '(+-parens-one-face
+                    +-parens-two-face
+                    +-parens-three-face
+                    +-parens-four-face
+                    +-parens-five-face
+                    +-parens-six-face
+                    +-parens-seven-face
+                    +-parens-eight-face
+                    +-parens-nine-face
+                    +-parens-ten-face))
+      (+-remove-overlays nil nil 'face face))
+    (setq +-parens-overlays-exist-p nil)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; AUTHOR:  Nikolaj Schumacher -- https://github.com/nschum/fringe-helper.el
+(defun +-fringe-helper-decimal (&rest strings)
+"Convert STRINGS into a vector usable for `define-fringe-bitmap'.
+Each string in STRINGS represents a line of the fringe bitmap.
+Periods (.) are background-colored pixel; Xs are foreground-colored. The
+fringe bitmap always is aligned to the right. If the fringe has half
+width, only the left 4 pixels of an 8 pixel bitmap will be shown.
+For example, the following code defines a diagonal line.
+\(+-fringe-helper-decimal
+\"XX......\"
+\"..XX....\"
+\"....XX..\"
+\"......XX\"\)"
+  (unless (cdr strings)
+    (setq strings (split-string (car strings) "\n")))
+  (apply 'vector
+    (mapcar
+      (lambda (str)
+        (let ((num 0))
+          (dolist (c (string-to-list str))
+            (setq num (+ (* num 2) (if (eq c ?.) 0 1))))
+          num))
+      strings)))
+
+;;; Modification by @lawlist of `+-fringe-helper-decimal' written by
+;;; Nikolaj Schumacher -- https://github.com/nschum/fringe-helper.el
+(defun +-fringe-helper-hexadecimal (&rest strings)
+"Convert STRINGS into a vector usable for `define-fringe-bitmap'.
+Each string in STRINGS represents a line of the fringe bitmap.
+Periods (.) are background-colored pixel; Xs are foreground-colored. The
+fringe bitmap always is aligned to the right. If the fringe has half
+width, only the left 4 pixels of an 8 pixel bitmap will be shown.
+For example, the following code defines a diagonal line.
+\(+-fringe-helper-hexadecimal
+\"XX......\"
+\"..XX....\"
+\"....XX..\"
+\"......XX\"\)"
+  (unless (cdr strings)
+    (setq strings (split-string (car strings) "\n")))
+  (mapconcat 'identity
+    (mapcar
+      (lambda (str)
+        (let ((num 0)
+              result)
+          (dolist (c (string-to-list str))
+            (setq num (+ (* num 2) (if (eq c ?.) 0 1))))
+          (if (= num 0)
+            "0x00"
+            (format "%#-x" num))))
+      strings)
+    ", "))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; FRINGE BITMAPS
+
+(define-fringe-bitmap '+-fringe-question-mark (+-fringe-helper-decimal
+"..xxxx.."
+".xxxxxx."
+"xx....xx"
+"xx....xx"
+"....xx.."
+"...xx..."
+"...xx..."
+"........"
+"...xx..."
+"...xx...") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-exclamation-mark (+-fringe-helper-decimal
+"...XX..."
+"...XX..."
+"...XX..."
+"...XX..."
+"...XX..."
+"...XX..."
+"...XX..."
+"........"
+"...XX..."
+"...XX...") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-left-arrow (+-fringe-helper-decimal
+"...xx..."
+"..xx...."
+".xx....."
+"xxxxxx.."
+"xxxxxx.."
+".xx....."
+"..xx...."
+"...xx...") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-right-arrow (+-fringe-helper-decimal
+"...xx..."
+"....xx.."
+".....xx."
+"..xxxxxx"
+"..xxxxxx"
+".....xx."
+"....xx.."
+"...xx...") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-up-arrow (+-fringe-helper-decimal
+"...xx..."
+"..xxxx.."
+".xxxxxx."
+"xxxxxxxx"
+"...xx..."
+"...xx..."
+"...xx..."
+"...xx...") nil nil 'top)
+
+(define-fringe-bitmap '+-fringe-down-arrow (+-fringe-helper-decimal
+"...xx..."
+"...xx..."
+"...xx..."
+"...xx..."
+"xxxxxxxx"
+".xxxxxx."
+"..xxxx.."
+"...xx...") nil nil 'bottom)
+
+(define-fringe-bitmap '+-fringe-left-curly-arrow (+-fringe-helper-decimal
+"...xxxx."
+"..xxxxx."
+".xx....."
+".xxx..x."
+".xxxxxx."
+"..xxxxx."
+"...xxxx."
+"..xxxxx.") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-right-curly-arrow (+-fringe-helper-decimal
+".xxxx..."
+".xxxxx.."
+".....xx."
+".x..xxx."
+".xxxxxx."
+".xxxxx.."
+".xxxx..."
+".xxxxx..") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-left-triangle (+-fringe-helper-decimal
+"......xx"
+"....xxxx"
+"...xxxxx"
+"..xxxxxx"
+"..xxxxxx"
+"...xxxxx"
+"....xxxx"
+"......xx") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-right-triangle (+-fringe-helper-decimal
+"xx......"
+"xxxx...."
+"xxxxx..."
+"xxxxxx.."
+"xxxxxx.."
+"xxxxx..."
+"xxxx...."
+"xx......") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-top-left-angle (+-fringe-helper-decimal
+"xxxxxx.."
+"xxxxxx.."
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"........") nil nil 'top)
+
+(define-fringe-bitmap '+-fringe-top-right-angle (+-fringe-helper-decimal
+"..xxxxxx"
+"..xxxxxx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"........") nil nil 'top)
+
+(define-fringe-bitmap '+-fringe-bottom-left-angle (+-fringe-helper-decimal
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xxxxxx.."
+"xxxxxx..") nil nil 'bottom)
+
+(define-fringe-bitmap '+-fringe-bottom-right-angle (+-fringe-helper-decimal
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"..xxxxxx"
+"..xxxxxx") nil nil 'bottom)
+
+(define-fringe-bitmap '+-fringe-left-bracket (+-fringe-helper-decimal
+"xxxxxx.."
+"xxxxxx.."
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xx......"
+"xxxxxx.."
+"xxxxxx..") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-right-bracket (+-fringe-helper-decimal
+"..xxxxxx"
+"..xxxxxx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"......xx"
+"..xxxxxx"
+"..xxxxxx") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-filled-rectangle (+-fringe-helper-decimal
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx."
+"xxxxxxx.") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-hollow-square (+-fringe-helper-decimal
+".xxxxxx."
+".x....x."
+".x....x."
+".x....x."
+".x....x."
+".xxxxxx.") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-filled-square (+-fringe-helper-decimal
+".xxxxxx."
+".xxxxxx."
+".xxxxxx."
+".xxxxxx."
+".xxxxxx."
+".xxxxxx.") nil nil 'center)
+
+(define-fringe-bitmap '+-fringe-horizontal-bar (+-fringe-helper-decimal
+"xxxxxxx."
+"xxxxxxx.") nil nil 'bottom)
+
+(define-fringe-bitmap '+-fringe-empty-line (+-fringe-helper-decimal
+"........"
+"..xxxx.."
+"........"
+"........"
+"..xxxx.."
+"........") nil nil '(top t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; `set-fringe-bitmap-face'
+
+(set-fringe-bitmap-face '+-smiley-face '+-left-fringe-current-line-face)
+
+(set-fringe-bitmap-face '+-hollow-rectangle '+-hollow-rectangle-face)
+
+(set-fringe-bitmap-face '+-backslash '+-backslash-face)
+
+(set-fringe-bitmap-face '+-fringe-question-mark '+-fringe-question-mark-face)
+
+(set-fringe-bitmap-face '+-fringe-exclamation-mark '+-fringe-exclamation-mark-face)
+
+(set-fringe-bitmap-face '+-fringe-left-arrow '+-fringe-left-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-right-arrow '+-fringe-right-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-up-arrow '+-fringe-up-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-down-arrow '+-fringe-down-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-left-curly-arrow '+-fringe-left-curly-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-right-curly-arrow '+-fringe-right-curly-arrow-face)
+
+(set-fringe-bitmap-face '+-fringe-left-triangle '+-fringe-left-triangle-face)
+
+(set-fringe-bitmap-face '+-fringe-right-triangle '+-fringe-right-triangle-face)
+
+(set-fringe-bitmap-face '+-fringe-top-left-angle '+-fringe-top-left-angle-face)
+
+(set-fringe-bitmap-face '+-fringe-top-right-angle '+-fringe-top-right-angle-face)
+
+(set-fringe-bitmap-face '+-fringe-bottom-left-angle '+-fringe-bottom-left-angle-face)
+
+(set-fringe-bitmap-face '+-fringe-bottom-right-angle '+-fringe-bottom-right-angle-face)
+
+(set-fringe-bitmap-face '+-fringe-left-bracket '+-fringe-left-bracket-face)
+
+(set-fringe-bitmap-face '+-fringe-right-bracket '+-fringe-right-bracket-face)
+
+(set-fringe-bitmap-face '+-fringe-filled-rectangle '+-fringe-filled-rectangle-face)
+
+(set-fringe-bitmap-face '+-fringe-hollow-square '+-fringe-hollow-square-face)
+
+(set-fringe-bitmap-face '+-fringe-filled-square '+-fringe-filled-square-face)
+
+(set-fringe-bitmap-face '+-fringe-horizontal-bar '+-fringe-horizontal-bar-face)
+
+(set-fringe-bitmap-face '+-fringe-empty-line '+-fringe-empty-line-face)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; FILL-COLUMN-MODE
+
+(defvar mc-fill-column-mode)
+
+(defvar mc-fill-column-timer-var nil
+"Timer used to highlight current column whenever Emacs is idle.")
+
+(defvar mc-fill-column-idle-timer-seconds 0.5
+  "The number of seconds to delay before drawing fill column when the variable
+`mc-fill-column-draw-forthwith' has a nil value.")
+
+(defun mc-fill-column-timer-fn ()
+"Since this fires globally, we must control which buffers fill column appear in."
+  (when mc-fill-column-mode
+    (when mc-fill-column-timer-var
+      (setq timer-idle-list (delq mc-fill-column-timer-var timer-idle-list))
+      (setq mc-fill-column-timer-var nil))
+    (when (and +-fill-column (null mc-fill-column-draw-forthwith))
+      (mc-activate-fill-column (selected-window)))))
+
+(defun mc-fill-column-draw-forthwith ()
+  "Force both rulers to be drawn/redrawn."
+  (mc-fill-column-draw 'force))
+
+(defun mc-fill-column-draw (&optional force)
+  (when mc-fill-column-mode
+    (when mc-fill-column-timer-var
+      (setq timer-idle-list (delq mc-fill-column-timer-var timer-idle-list))
+      (setq mc-fill-column-timer-var nil))
+    (if force
+      (when (and +-fill-column (null mc-fill-column-draw-forthwith))
+        (mc-activate-fill-column (selected-window)))
+      (setq mc-fill-column-timer-var (run-with-idle-timer mc-fill-column-idle-timer-seconds nil #'mc-fill-column-timer-fn)))))
+
+;;;###autoload
+(define-minor-mode mc-fill-column-mode
+"Minor mode for displaying a visual fill column."
+  :init-value nil
+  :lighter " FC"
+  :keymap nil
+  :global nil
+  :group 'mc-fill-column-mode
+  (cond
+    ;;; `+-mode' has the ability to also display a fill column indicator.
+    ;;; See the variable `+-fill-column'.
+    ((and mc-fill-column-mode +-mode)
+      (setq mc-fill-column-mode nil)
+      (message "Turned OFF `mc-fill-column-mode' (%s) -- see the variable `+-fill-column'." (current-buffer)))
+    (mc-fill-column-mode
+      (when (and global-eldoc-mode
+                 (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (global-eldoc-mode -1))
+      (when (and jit-lock-context-timer
+                 (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (when (timerp jit-lock-context-timer)
+          (cancel-timer jit-lock-context-timer))
+        ;; (setq jit-lock-context-timer (run-with-idle-timer 5.0 'repeat 'jit-lock-context-fontify))
+        (setq jit-lock-context-timer nil))
+      (when (and (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4)))
+        (when (timerp undo-auto-current-boundary-timer)
+          (cancel-timer undo-auto-current-boundary-timer))
+        (fset 'undo-auto--undoable-change
+              (lambda () (add-to-list 'undo-auto--undoably-changed-buffers (current-buffer))))
+        (fset 'undo-auto-amalgamate 'ignore))
+      (when blink-cursor-mode
+        (blink-cursor-mode -1)
+        (when (memq 'blink-cursor-check post-command-hook)
+          (remove-hook 'post-command-hook 'blink-cursor-check)))
+      (when (and (called-interactively-p 'any)
+                 (equal current-prefix-arg '(4))
+                 (null mc-fill-column-draw-forthwith))
+        (setq mc-fill-column-draw-forthwith t))
+      (setq mc-fill-column t)
+      ;;; `auto-composition-mode' is needed for crosshairs to properly calculate
+      ;;; coordinates of composition characters.  Automatically becomes permanently
+      ;;; buffer-local when set.
+      (unless auto-composition-mode
+        (setq auto-composition-mode t))
+      ;;; @lawlist is focusing the initial development of feature requests #17684
+      ;;; and #22873 on L2R languages.  The feature test file used by @lawlist
+      ;;; bogs Emacs down unless `bidi-display-reordering' is set to a nil value.
+      ;;; However, most users will probably not want this particular setting.
+      (unless (null bidi-display-reordering)
+        (setq bidi-display-reordering nil))
+      (unless (and (called-interactively-p 'any)
+                   (equal current-prefix-arg '(4)))
+        (setq fill-column 80)
+        (if mc-fill-column-draw-forthwith
+          (add-hook 'post-command-hook 'mc-fill-column-draw-forthwith 'append 'local)
+          (add-hook 'post-command-hook 'mc-fill-column-draw 'append 'local))
+        (when mc-fill-column-draw-forthwith
+          (add-hook 'window-configuration-change-hook 'mc-fill-column-draw-forthwith nil 'local))
+        (add-hook 'change-major-mode-hook 'turn-off-mc-fill-column-mode nil 'local))
+      (when (called-interactively-p 'any)
+        (if (equal current-prefix-arg '(4))
+          (message "Turned ON `mc-fill-column-mode' -- debugging mode.")
+          (message "Turned ON `mc-fill-column-mode'."))))
+    (t
+      (kill-local-variable 'fill-column)
+      (kill-local-variable 'mc-fill-column)
+      (when (memq 'mc-fill-column-draw-forthwith post-command-hook)
+        (remove-hook 'post-command-hook 'mc-fill-column-draw-forthwith 'local))
+      (when (memq 'mc-fill-column-draw-crosshairs post-command-hook)
+        (remove-hook 'post-command-hook 'mc-fill-column-draw-crosshairs 'local))
+      (when (memq 'mc-fill-column-draw-forthwith window-configuration-change-hook)
+        (remove-hook 'window-configuration-change-hook 'mc-fill-column-draw-forthwith 'local))
+      (remove-hook 'change-major-mode-hook 'turn-off-mc-fill-column-mode 'local)
+      (when mc-fill-column-timer-var
+        (setq timer-idle-list (delq mc-fill-column-timer-var timer-idle-list))
+        (setq mc-fill-column-timer-var nil))
+      (when (called-interactively-p 'any)
+        (message "Turned OFF `mc-fill-column-mode'.")))))
+
+(defun turn-off-mc-fill-column-mode ()
+  (mc-fill-column-mode -1))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'crosshairs)
\ No newline at end of file
diff --git a/lisp/faces.el b/lisp/faces.el
index a8c1546..a61227e 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2502,6 +2502,270 @@ unwanted effects."
   :group 'basic-faces
   :group 'display-line-numbers)
 
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; begin MULTIPLE CURSORS
+
+(defface +-vertical-bar-face
+  '((t (:foreground "magenta")))
+  "Face for `+-vertical-bar-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-even-numbered-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "purple")
+    (((class color) (min-colors 88) (background light))
+     :foreground "purple")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-numbered-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-odd-numbered-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "red")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "red")
+    (((class color) (min-colors 88) (background light))
+     :foreground "red")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-numbered-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-even-numbered-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#eee8aa")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "purple3")
+    (((class color) (min-colors 88) (background light))
+     :foreground "purple3")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-numbered-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-odd-numbered-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff6347")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "orange")
+    (((class color) (min-colors 88) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-numbered-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-beyond-fill-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "green")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "green")
+    (((class color) (min-colors 88) (background light))
+     :foreground "green")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-beyond-fill-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+
+(defface +-beyond-fill-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 88) (background light))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-beyond-fill-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "cyan" :background "DarkBlue")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color" :background "gtk_selection_bg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "black" :background "LightSkyBlue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "black" :background "LightSkyBlue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the border and
+the :background parameter is used for the inner filled shading.  The character
+retains its own foreground color and is unaffected by this particular face."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff00ff" :background "ForestGreen")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color" :background "gtk_selection_bg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "black" :background "grey70")
+    (((class color) (min-colors 88) (background light))
+     :foreground "black" :background "grey70")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-inactive-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the border and
+the :background parameter is used for the inner filled shading.  The character
+retains its own foreground color and is unaffected by this particular face."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-region-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "grey15" :background "#8b795e")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "gtk_selection_fg_color" :background "gtk_selection_bg_color")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "pink" :background "#8b795e")
+    (((class color) (min-colors 88) (background light))
+     :foreground "pink" :background "#8b795e")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-region-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the inner
+filled shading when PT is _not_ within the active region; and, the :background
+parameter is used for the inner filled shading when PT _is_ within the active
+region.  The character retains its own foreground color and is unaffected by this
+particular face."
+  :group '+-mode)
+
+(defface +-overlay-arrow-face
+  '((t (:foreground "red")))
+  "Face for `+-overlay-arrow-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-minimal-face
+  '((t (:foreground "blue")))
+  "Face for `+-overlay-arrow-minimal-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-inactive-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-inactive-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-face
+  '((t (:foreground "DarkGreen")))
+  "Face for `+-overlay-arrow-hscl-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-minimal-face
+  '((t (:foreground "SaddleBrown")))
+  "Face for `+-overlay-arrow-hscl-minimal-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-inactive-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-hscl-inactive-face'."
+  :group '+-mode)
+
+(defface mc-fill-column-face
+  '((t (:foreground "grey15")))
+  "Face for `mc-fill-column-face' in the active window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface mc-fill-column-inactive-face
+  '((t (:foreground "DarkBlue")))
+  "Face for `mc-fill-column-inactive-face' in the inactive window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface mc-fill-column-opoint-face
+  '((t (:foreground "magenta")))
+  "Face for `mc-fill-column-opoint-face' in the active window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface mc-fill-column-opoint-inactive-face
+  '((t (:foreground "cyan")))
+  "Face for `mc-fill-column-opoint-inactive-face' in the inactive window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+;;; end MULTIPLE CURSORS
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
 (defface escape-glyph
   '((((background dark)) :foreground "cyan")
     ;; See the comment in minibuffer-prompt for
diff --git a/src/buffer.c b/src/buffer.c
index 90ef886..7912e5e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5097,6 +5097,28 @@ init_buffer_once (void)
   bset_last_selected_window (&buffer_local_flags, make_fixnum (0));
 
   idx = 1;
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_real_fake_cursor), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, multiple_cursors_conf), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, multiple_cursors_draw_forthwith), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, multiple_cursors_inactive_windows), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs_horizontal_ruler), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs_vertical_ruler), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs_draw_forthwith), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs_inactive_windows), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_stderr), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_fill_column), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_fill_column_draw_forthwith), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_fill_column_inactive_windows), 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;
@@ -5178,6 +5200,28 @@ init_buffer_once (void)
   /* Must do these before making the first buffer! */
 
   /* real setup is done in bindings.el */
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  bset_blv_mc_real_fake_cursor (&buffer_defaults, Qhollow);
+  bset_blv_multiple_cursors_conf (&buffer_defaults, Qnil);
+  bset_blv_multiple_cursors_draw_forthwith (&buffer_defaults, Qt);
+  bset_blv_multiple_cursors_inactive_windows (&buffer_defaults, Qt);
+  bset_blv_crosshairs (&buffer_defaults, Qnil);
+  bset_blv_crosshairs_horizontal_ruler (&buffer_defaults, Qt);
+  bset_blv_crosshairs_vertical_ruler (&buffer_defaults, Qt);
+  bset_blv_crosshairs_draw_forthwith (&buffer_defaults, Qnil);
+  bset_blv_crosshairs_inactive_windows (&buffer_defaults, Qt);
+  bset_blv_mc_stderr (&buffer_defaults, Qnil);
+  bset_blv_mc_fill_column (&buffer_defaults, Qnil);
+  bset_blv_mc_fill_column_draw_forthwith (&buffer_defaults, Qnil);
+  bset_blv_mc_fill_column_inactive_windows (&buffer_defaults, Qt);
+
+/* *************************************************************************** */
+
+
   bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
   bset_header_line_format (&buffer_defaults, Qnil);
   bset_abbrev_mode (&buffer_defaults, Qnil);
@@ -5416,6 +5460,27 @@ syms_of_buffer (void)
   staticpro (&QSFundamental);
   staticpro (&Vbuffer_alist);
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  DEFSYM (Qmc_real_fake_cursor, "mc-real-fake-cursor");
+  DEFSYM (Qmultiple_cursors_conf, "multiple-cursors-conf");
+  DEFSYM (Qmultiple_cursors_draw_forthwith, "multiple-cursors-draw-forthwith");
+  DEFSYM (Qmultiple_cursors_inactive_windows, "multiple-cursors-inactive-windows");
+  DEFSYM (Qcrosshairs, "crosshairs");
+  DEFSYM (Qcrosshairs_horizontal_ruler, "crosshairs-horizontal-ruler");
+  DEFSYM (Qcrosshairs_vertical_ruler, "crosshairs-vertical-ruler");
+  DEFSYM (Qcrosshairs_draw_forthwith, "crosshairs-draw-forthwith");
+  DEFSYM (Qcrosshairs_inactive_windows, "crosshairs-inactive-windows");
+  DEFSYM (Qmc_stderr, "mc-stderr");
+  DEFSYM (Qmc_fill_column, "mc-fill-column");
+  DEFSYM (Qmc_fill_column_draw_forthwith, "mc-fill-column-draw-forthwith");
+  DEFSYM (Qmc_fill_column_inactive_window, "mc-fill-column-inactive-window");
+
+/* *************************************************************************** */
+
+
   DEFSYM (Qchoice, "choice");
   DEFSYM (Qleft, "left");
   DEFSYM (Qright, "right");
@@ -5453,6 +5518,65 @@ syms_of_buffer (void)
   Fput (Qprotected_field, Qerror_message,
 	build_pure_c_string ("Attempt to modify a protected field"));
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  DEFVAR_PER_BUFFER ("mc-real-fake-cursor", &BVAR (current_buffer, mc_real_fake_cursor), Qnil,
+    doc: /* A bufer-local variable to set the cursor type of the real fake cursor. */);
+
+  DEFVAR_PER_BUFFER ("multiple-cursors-conf", &BVAR (current_buffer, multiple_cursors_conf), Qnil,
+    doc: /* A bufer-local variable to store the value of the multiple cursors to be displayed
+during the next redisplay. */);
+
+  DEFVAR_PER_BUFFER ("multiple-cursors-draw-forthwith", &BVAR (current_buffer, multiple_cursors_draw_forthwith), Qnil,
+    doc: /* When non-nil, draw multiple cursors whenever the real cursor would
+ordinarily be drawn, which is sometimes more than once every command loop.
+When nil, multiple-cursors will be placed on an idle-timer.  If this variable is
+reset while `multiple-cursors-mode' is enabled, then it may be necessary to turn off/on
+`multiple-cursors-mode' to reset functions attached to the `post-command-hook'. */);
+
+  DEFVAR_PER_BUFFER ("multiple-cursors-inactive-windows", &BVAR (current_buffer, multiple_cursors_inactive_windows), Qnil,
+    doc: /* When non-nil, draw multiple cursors in inactive windows. */);
+
+  DEFVAR_PER_BUFFER ("crosshairs", &BVAR (current_buffer, crosshairs), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate crosshairs. */);
+
+  DEFVAR_PER_BUFFER ("crosshairs-horizontal-ruler", &BVAR (current_buffer, crosshairs_horizontal_ruler), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate the crosshairs horizontal ruler. */);
+
+  DEFVAR_PER_BUFFER ("crosshairs-vertical-ruler", &BVAR (current_buffer, crosshairs_vertical_ruler), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate the crosshairs vertical ruler. */);
+
+  DEFVAR_PER_BUFFER ("crosshairs-draw-forthwith", &BVAR (current_buffer, crosshairs_draw_forthwith), Qnil,
+    doc: /* When non-nil, draw crosshairs whenever the real cursor would
+ordinarily be drawn, which is sometimes more than once every command loop.
+When nil, crosshairs will be placed on an idle-timer.  If this variable is
+reset while `+-mode' is enabled, then it may be necessary to turn off/on
+`+-mode' to reset functions attached to the `post-command-hook'. */);
+
+  DEFVAR_PER_BUFFER ("crosshairs-inactive-windows", &BVAR (current_buffer, crosshairs_inactive_windows), Qnil,
+    doc: /* When non-nil, draw crosshairs in inactive windows. */);
+
+  DEFVAR_PER_BUFFER ("mc-stderr", &BVAR (current_buffer, mc_stderr), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate debugging messages to stderr. */);
+
+  DEFVAR_PER_BUFFER ("mc-fill-column", &BVAR (current_buffer, mc_fill_column), Qnil,
+    doc: /* A bufer-local variable to turn on/off the multiple cursors fill column. */);
+
+  DEFVAR_PER_BUFFER ("mc-fill-column-draw-forthwith", &BVAR (current_buffer, mc_fill_column_draw_forthwith), Qnil,
+    doc: /* When non-nil, draw multiple cursors fill column whenever the real cursor would
+ordinarily be drawn, which is sometimes more than once every command loop.
+When nil, the multiple cursors fill column will be placed on an idle-timer.  If this variable
+is reset while `mc-fill-column-mode' is enabled, then it may be necessary to turn off/on
+`mc-fill-column-mode' to reset functions attached to the `post-command-hook'. */);
+
+  DEFVAR_PER_BUFFER ("mc-fill-column-inactive-windows", &BVAR (current_buffer, mc_fill_column_inactive_windows), Qnil,
+    doc: /* When non-nil, draw multiple cursors fill column in inactive windows. */);
+
+/* *************************************************************************** */
+
+
   DEFVAR_PER_BUFFER ("header-line-format",
 		     &BVAR (current_buffer, header_line_format),
 		     Qnil,
diff --git a/src/buffer.h b/src/buffer.h
index 4ea7fa6..2305f47 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -636,6 +636,52 @@ struct buffer
      cache are enabled.  See search.c, indent.c and bidi.c for details.  */
   Lisp_Object cache_long_scans_;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  /* The cursor type of the real fake cursor. */
+  Lisp_Object mc_real_fake_cursor_;
+
+  /* The name of list used by multiple cursors for next redisplay. */
+  Lisp_Object multiple_cursors_conf_;
+
+  /* Whether to draw multiple cursors immediately, or on an idle-timer. */
+  Lisp_Object multiple_cursors_draw_forthwith_;
+
+  /* Whether to draw multiple cursors in inactive windows. */
+  Lisp_Object multiple_cursors_inactive_windows_;
+
+  /* The name of the buffer-local variable. */
+  Lisp_Object crosshairs_;
+
+  /* The name of the crosshairs horizontal ruler. */
+  Lisp_Object crosshairs_horizontal_ruler_;
+
+  /* The name of the crosshairs vertical ruler. */
+  Lisp_Object crosshairs_vertical_ruler_;
+
+  /* Whether to draw crosshairs immediately, or on an idle-timer. */
+  Lisp_Object crosshairs_draw_forthwith_;
+
+  /* Whether to draw crosshairs in inactive windows. */
+  Lisp_Object crosshairs_inactive_windows_;
+
+  /* Used in conjunction with generating stderr debugging message. */
+  Lisp_Object mc_stderr_;
+
+  /* The name of the buffer-local variable. */
+  Lisp_Object mc_fill_column_;
+
+  /* Whether to draw multiple cursors fill column immediately, or on an idle-timer. */
+  Lisp_Object mc_fill_column_draw_forthwith_;
+
+  /* Whether to draw multiple cursors fill column in inactive windows. */
+  Lisp_Object mc_fill_column_inactive_windows_;
+
+/* *************************************************************************** */
+
+
   /* 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
@@ -792,9 +838,17 @@ struct buffer
      for a buffer-local variable is stored in that variable's slot
      in buffer_local_flags as a Lisp integer.  If the index is -1,
      this means the variable is always local in all buffers.  */
-#define MAX_PER_BUFFER_VARS 50
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+#define MAX_PER_BUFFER_VARS 60
   char local_flags[MAX_PER_BUFFER_VARS];
 
+/* *************************************************************************** */
+
+
   /* Set to the modtime of the visited file when read or written.
      modtime.tv_nsec == NONEXISTENT_MODTIME_NSECS means
      visited file was nonexistent.  modtime.tv_nsec ==
@@ -896,6 +950,92 @@ XBUFFER (Lisp_Object a)
 /* Most code should use these functions to set Lisp fields in struct
    buffer.  (Some setters that are private to a single .c file are
    defined as static in those files.)  */
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+INLINE void
+bset_blv_mc_real_fake_cursor (struct buffer *b, Lisp_Object val)
+{
+  b->mc_real_fake_cursor_ = val;
+}
+
+INLINE void
+bset_blv_multiple_cursors_conf (struct buffer *b, Lisp_Object val)
+{
+  b->multiple_cursors_conf_ = val;
+}
+
+INLINE void
+bset_blv_multiple_cursors_draw_forthwith (struct buffer *b, Lisp_Object val)
+{
+  b->multiple_cursors_draw_forthwith_ = val;
+}
+
+INLINE void
+bset_blv_multiple_cursors_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->multiple_cursors_inactive_windows_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs_horizontal_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_horizontal_ruler_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs_vertical_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_vertical_ruler_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs_draw_forthwith (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_draw_forthwith_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_inactive_windows_ = val;
+}
+
+INLINE void
+bset_blv_mc_stderr (struct buffer *b, Lisp_Object val)
+{
+  b->mc_stderr_ = val;
+}
+
+INLINE void
+bset_blv_mc_fill_column (struct buffer *b, Lisp_Object val)
+{
+  b->mc_fill_column_ = val;
+}
+
+INLINE void
+bset_blv_mc_fill_column_draw_forthwith (struct buffer *b, Lisp_Object val)
+{
+  b->mc_fill_column_draw_forthwith_ = val;
+}
+
+INLINE void
+bset_blv_mc_fill_column_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->mc_fill_column_inactive_windows_ = val;
+}
+
+/* *************************************************************************** */
+
+
 INLINE void
 bset_bidi_paragraph_direction (struct buffer *b, Lisp_Object val)
 {
diff --git a/src/dispextern.h b/src/dispextern.h
index 579665c..b5ee135 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -94,6 +94,28 @@ typedef int Cursor;
 #define NativeRectangle int
 #endif
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+enum mc_types
+{
+  NO_FLAVOR,
+  MC_GLYPH,
+  MC_GLYPHLESS,
+  MC_GLYPH_TAB,
+  MC_OVERLAY_ARROW_BITMAP,
+  MC_PILCROW,
+  MC_HOLLOW_RECTANGLE_RIGHT_ARROW,
+  MC_HOLLOW_RECTANGLE,
+  MC_VERTICAL_BAR_RIGHT_ARROW,
+  MC_VERTICAL_BAR,
+  MC_VERTICAL_BAR_BACKSLASH
+};
+
+/* *************************************************************************** */
+
+
 /* Text cursor types.  */
 
 enum text_cursor_kinds
@@ -376,6 +398,18 @@ struct glyph_slice
 
 struct glyph
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  int x, y, hpos, vpos;
+
+  bool_bf zv_p : 1;
+
+/* *************************************************************************** */
+
+
   /* Position from which this glyph was drawn.  If `object' below is a
      Lisp string, this is an index into that string.  If it is a
      buffer, this is a position in that buffer.  In addition, some
@@ -2210,6 +2244,16 @@ struct composition_it
 
 struct it
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  bool_bf zv_p : 1;
+
+/* *************************************************************************** */
+
+
   /* The window in which we iterate over current_buffer (or a string).  */
   Lisp_Object window;
   struct window *w;
diff --git a/src/frame.h b/src/frame.h
index ad7376a..31d9527 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -202,6 +202,16 @@ struct frame
 
   /* Beyond here, there should be no more Lisp_Object components.  */
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  /* Non-nil when the frame is in the process of being updated. */
+  struct frame *mc_updating_frame;
+
+/* *************************************************************************** */
+
+
   /* Cache of realized faces.  */
   struct face_cache *face_cache;
 
diff --git a/src/fringe.c b/src/fringe.c
index a1016ad..2a5573a 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -433,6 +433,402 @@ static unsigned short empty_line_bits[] = {
   0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
 
 
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
+
+/* `+-fringe-helper-decimal' defined in `crosshairs.el` */
+
+/* 24
+    (+-fringe-helper-hexadecimal
+      "x......."
+      "x......."
+      "x......."
+      "x..xx..."
+      "x...xx.."
+      "x....xx."
+      "x.xxxxxx"
+      "x.xxxxxx"
+      "x....xx."
+      "x...xx.."
+      "x..xx..."
+      "x......."
+      "x......."
+      "x.......")
+*/
+static unsigned short mc_vertical_bar_right_arrow_bits[] ={
+  0x80, 0x80, 0x80, 0x98, 0x8c, 0x86, 0xbf,
+  0xbf, 0x86, 0x8c, 0x98, 0x80, 0x80, 0x80};
+
+/* 25
+    (+-fringe-helper-hexadecimal
+      "xxxxxxxx"
+      "x......x"
+      "x......x"
+      "x..xx..x"
+      "x...xx.x"
+      "x....xxx"
+      "x.xxxxxx"
+      "x.xxxxxx"
+      "x....xxx"
+      "x...xx.x"
+      "x..xx..x"
+      "x......x"
+      "x......x"
+      "xxxxxxxx")
+*/
+static unsigned short mc_hollow_rectangle_right_arrow_bits[] ={
+  0xff, 0x81, 0x81, 0x99, 0x8d, 0x87, 0xbf,
+  0xbf, 0x87, 0x8d, 0x99, 0x81, 0x81, 0xff};
+
+/* 26
+    (+-fringe-helper-hexadecimal
+      "xxxxxxxx"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "x......x"
+      "xxxxxxxx")
+*/
+static unsigned short mc_hollow_rectangle_bits[] ={
+  0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+  0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff};
+
+/* 27
+    (+-fringe-helper-hexadecimal
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x......."
+      "x.......")
+*/
+static unsigned short mc_vertical_bar_bits[] ={
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
+
+/* 28
+    (+-fringe-helper-hexadecimal
+      "xx......"
+      "xx......"
+      " xx....."
+      ".xx....."
+      "..xx...."
+      "..xx...."
+      "...xx..."
+      "...xx..."
+      "....xx.."
+      "....xx.."
+      ".....xx."
+      ".....xx."
+      "......xx"
+      "......xx")
+*/
+static unsigned short mc_backslash_bits[] ={
+  0xc0, 0xc0, 0xe0, 0x60, 0x30, 0x30, 0x18, 0x18, 0xc, 0xc, 0x6, 0x6, 0x3, 0x3};
+
+/* 29
+    (+-fringe-helper-hexadecimal
+      "xx......"
+      "xx......"
+      "xxx....."
+      "xxx....."
+      "x.xx...."
+      "x.xx...."
+      "x..xx..."
+      "x..xx..."
+      "x...xx.."
+      "x...xx.."
+      "x....xx."
+      "x....xx."
+      "x.....xx"
+      "x.....xx")
+*/
+static unsigned short mc_vertical_bar_backslash_bits[] ={
+  0xc0, 0xc0, 0xe0, 0xe0, 0xb0, 0xb0, 0x98,
+  0x98, 0x8c, 0x8c, 0x86, 0x86, 0x83, 0x83};
+
+/* 30
+    (+-fringe-helper-hexadecimal
+      ".xxxxxx."
+      "xxxx.x.."
+      "xxxx.x.."
+      "xxxx.x.."
+      ".xxx.x.."
+      "...x.x.."
+      "...x.x.."
+      "...x.x.."
+      "...x.x.."
+      "...x.x.."
+      "...x.x..")
+*/
+static unsigned short mc_pilcrow_bits[] ={
+  0x7e, 0xf4, 0xf4, 0xf4, 0x74, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14};
+
+/* 31
+    (+-fringe-helper-hexadecimal
+      "..xxxx.."
+      ".xxxxxx."
+      "x..xx..x"
+      "x..xx..x"
+      "xxxxxxxx"
+      "xx....xx"
+      "xxx..xxx"
+      ".xxxxxx."
+      "..xxxx..")
+*/
+static unsigned short mc_smiley_face_bits[] ={
+  0x3c, 0x7e, 0x99, 0x99, 0xff, 0xc3, 0xe7, 0x7e, 0x3c};
+
+/* 32
+    (+-fringe-helper-hexadecimal
+      "..x....."
+      "...x...."
+      "....x..."
+      ".....x.."
+      "....x..."
+      "...x...."
+      "..x.....")
+*/
+static unsigned short mc_single_angle_right_bits[] ={
+  0x20, 0x10, 0x8, 0x4, 0x8, 0x10, 0x20};
+
+/* 33
+    (+-fringe-helper-hexadecimal
+      ".....x.."
+      "....x..."
+      "...x...."
+      "..x....."
+      "...x...."
+      "....x..."
+      ".....x..")
+*/
+static unsigned short mc_single_angle_left_bits[] ={
+  0x4, 0x8, 0x10, 0x20, 0x10, 0x8, 0x4};
+
+/* 34
+    (+-fringe-helper-hexadecimal
+      "xx.xx..."
+      ".xx.xx.."
+      "..xx.xx."
+      "...xx.xx"
+      "..xx.xx."
+      ".xx.xx.."
+      "xx.xx...")
+*/
+static unsigned short mc_double_angle_right_bits[] ={
+  0xd8, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0xd8};
+
+/* 35
+    (+-fringe-helper-hexadecimal
+      "...xx.xx"
+      "..xx.xx."
+      ".xx.xx.."
+      "xx.xx..."
+      ".xx.xx.."
+      "..xx.xx."
+      "...xx.xx")
+*/
+static unsigned short mc_double_angle_left_bits[] ={
+  0x1b, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x1b};
+
+/* 36
+    (+-fringe-helper-hexadecimal
+      "x.x.x..."
+      ".x.x.x.."
+      "..x.x.x."
+      "...x.x.x"
+      "..x.x.x."
+      ".x.x.x.."
+      "x.x.x...")
+*/
+static unsigned short mc_triple_angle_right_bits[] ={
+  0xa8, 0x54, 0x2a, 0x15, 0x2a, 0x54, 0xa8};
+
+/* 37
+    (+-fringe-helper-hexadecimal
+      "...x.x.x"
+      "..x.x.x."
+      ".x.x.x.."
+      "x.x.x..."
+      ".x.x.x.."
+      "..x.x.x."
+      "...x.x.x")
+*/
+static unsigned short mc_triple_angle_left_bits[] ={
+  0x15, 0x2a, 0x54, 0xa8, 0x54, 0x2a, 0x15};
+
+/* 38
+    (+-fringe-helper-hexadecimal
+      "........"
+      "........"
+      "........"
+      "........"
+      "...x...."
+      "..x.x..."
+      ".x...x.."
+      "x.....x."
+      "........"
+      "........"
+      "........"
+      "........")
+*/
+static unsigned short mc_single_angle_up_bits[] ={
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00};
+
+/* 39
+    (+-fringe-helper-hexadecimal
+      "........"
+      "........"
+      "........"
+      "........"
+      "x.....x."
+      ".x...x.."
+      "..x.x..."
+      "...x...."
+      "........"
+      "........"
+      "........"
+      "........")
+*/
+static unsigned short mc_single_angle_down_bits[] ={
+  0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00};
+
+/* 40
+    (+-fringe-helper-hexadecimal
+      "........"
+      "........"
+      "........"
+      "...x...."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x.....x."
+      "........"
+      "........"
+      "........")
+*/
+static unsigned short mc_double_angle_up_bits[] ={
+  0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x92, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00};
+
+/* 41
+    (+-fringe-helper-hexadecimal
+      "........"
+      "........"
+      "........"
+      "x.....x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "...x...."
+      "........"
+      "........"
+      "........")
+*/
+static unsigned short mc_double_angle_down_bits[] ={
+  0x00, 0x00, 0x00, 0x82, 0x44, 0x28, 0x92, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00};
+
+/* 42
+    (+-fringe-helper-hexadecimal
+      "........"
+      "...x...."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x.....x."
+      "........")
+*/
+static unsigned short mc_triple_angle_up_bits[] ={
+  0x00, 0x10, 0x28, 0x44, 0x92, 0x28, 0x44, 0x92, 0x28, 0x44, 0x82, 0x00};
+
+/* 43
+    (+-fringe-helper-hexadecimal
+      "........"
+      "x.....x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "...x...."
+      "........")
+*/
+static unsigned short mc_quadruple_angle_down_bits[] ={
+  0x00, 0x82, 0x44, 0x28, 0x92, 0x44, 0x28, 0x92, 0x44, 0x28, 0x10, 0x00};
+
+/* 44
+    (+-fringe-helper-hexadecimal
+      "...x...."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x..x..x."
+      "..x.x..."
+      ".x...x.."
+      "x.....x.")
+*/
+static unsigned short mc_quadruple_angle_up_bits[] ={
+  0x10, 0x28, 0x44, 0x92, 0x28, 0x44, 0x92, 0x28, 0x44, 0x92, 0x28, 0x44, 0x82};
+
+/* 45
+    (+-fringe-helper-hexadecimal
+      "x.....x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "x..x..x."
+      ".x...x.."
+      "..x.x..."
+      "...x....")
+*/
+static unsigned short mc_triple_angle_down_bits[] ={
+  0x82, 0x44, 0x28, 0x92, 0x44, 0x28, 0x92, 0x44, 0x28, 0x92, 0x44, 0x28, 0x10};
+
+/* TODO:  Add the following bitmaps:
+  (define-fringe-bitmap 'breakpoint "\x3c\x7e\xff\xff\xff\xff\x7e\x3c")
+  (define-fringe-bitmap 'hollow-right-triangle "\xe0\x90\x88\x84\x84\x88\x90\xe0") */
+
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
+
+
 #define BYTES_PER_BITMAP_ROW  (sizeof (unsigned short))
 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
 #define FRBITS(bits)  bits, STANDARD_BITMAP_HEIGHT (bits)
@@ -466,6 +862,59 @@ static struct fringe_bitmap standard_bitmaps[] =
   { FRBITS (vertical_bar_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
   { FRBITS (horizontal_bar_bits),     8, 0, ALIGN_BITMAP_BOTTOM, 0 },
   { FRBITS (empty_line_bits),         8, 3, ALIGN_BITMAP_TOP,    0 },
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  /* 24 */
+  { FRBITS (mc_vertical_bar_right_arrow_bits),     8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 25 */
+  { FRBITS (mc_hollow_rectangle_right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 26 */
+  { FRBITS (mc_hollow_rectangle_bits),             8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 27 */
+  { FRBITS (mc_vertical_bar_bits),                 8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 28 */
+  { FRBITS (mc_backslash_bits),                    8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 29 */
+  { FRBITS (mc_vertical_bar_backslash_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 30 */
+  { FRBITS (mc_pilcrow_bits),                      8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 31 */
+  { FRBITS (mc_smiley_face_bits),                  8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 32 */
+  { FRBITS (mc_single_angle_right_bits),           8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 33 */
+  { FRBITS (mc_single_angle_left_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 34 */
+  { FRBITS (mc_double_angle_right_bits),           8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 35 */
+  { FRBITS (mc_double_angle_left_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 36 */
+  { FRBITS (mc_triple_angle_right_bits),           8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 37 */
+  { FRBITS (mc_triple_angle_left_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 38 */
+  { FRBITS (mc_single_angle_up_bits),              8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 39 */
+  { FRBITS (mc_single_angle_down_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 40 */
+  { FRBITS (mc_double_angle_up_bits),              8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 41 */
+  { FRBITS (mc_double_angle_down_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 42 */
+  { FRBITS (mc_triple_angle_up_bits),              8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 43 */
+  { FRBITS (mc_triple_angle_down_bits),            8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 44 */
+  { FRBITS (mc_quadruple_angle_up_bits),           8, 0, ALIGN_BITMAP_CENTER, 0 },
+  /* 45 */
+  { FRBITS (mc_quadruple_angle_down_bits),         8, 0, ALIGN_BITMAP_CENTER, 0 },
+
+/* *************************************************************************** */
+
+
 };
 
 #define NO_FRINGE_BITMAP 0
@@ -1723,6 +2172,150 @@ If nil, also continue lines which are exactly as wide as the window.  */);
   DEFVAR_LISP ("fringe-bitmaps", Vfringe_bitmaps,
     doc: /* List of fringe bitmap symbols.  */);
   Vfringe_bitmaps = Qnil;
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
+
+  /* (get 'empty-line 'fringe) => 23 => the last standard-bitmap before this one.
+  See `fringe.el`. */
+
+  /* 24 */
+  DEFSYM (Qmc_vertical_bar_right_arrow, "+-vertical-bar-right-arrow");
+  Vfringe_bitmaps = Fcons (Qmc_vertical_bar_right_arrow, Vfringe_bitmaps);
+  Fput (Qmc_vertical_bar_right_arrow, Qfringe, make_fixnum (24));
+  /* (get '+-vertical-bar-right-arrow 'fringe) => 24 */
+
+  /* 25 */
+  DEFSYM (Qmc_hollow_rectangle_right_arrow, "+-hollow-rectangle-right-arrow");
+  Vfringe_bitmaps = Fcons (Qmc_hollow_rectangle_right_arrow, Vfringe_bitmaps);
+  Fput (Qmc_hollow_rectangle_right_arrow, Qfringe, make_fixnum (25));
+  /* (get '+-hollow-rectangle-right-arrow 'fringe) => 25 */
+
+  /* 26 */
+  DEFSYM (Qmc_hollow_rectangle, "+-hollow-rectangle");
+  Vfringe_bitmaps = Fcons (Qmc_hollow_rectangle, Vfringe_bitmaps);
+  Fput (Qmc_hollow_rectangle, Qfringe, make_fixnum (26));
+  /* (get '+-hollow-rectangle 'fringe) => 26 */
+
+  /* 27 */
+  DEFSYM (Qmc_vertical_bar, "+-vertical-bar");
+  Vfringe_bitmaps = Fcons (Qmc_vertical_bar, Vfringe_bitmaps);
+  Fput (Qmc_vertical_bar, Qfringe, make_fixnum (27));
+  /* (get '+-vertical-bar 'fringe) => 27 */
+
+  /* 28 */
+  DEFSYM (Qmc_backslash, "+-backslash");
+  Vfringe_bitmaps = Fcons (Qmc_backslash, Vfringe_bitmaps);
+  Fput (Qmc_backslash, Qfringe, make_fixnum (28));
+  /* (get '+-backslash 'fringe) => 28 */
+
+  /* 29 */
+  DEFSYM (Qmc_vertical_bar_backslash, "+-vertical-bar-backslash");
+  Vfringe_bitmaps = Fcons (Qmc_vertical_bar_backslash, Vfringe_bitmaps);
+  Fput (Qmc_vertical_bar_backslash, Qfringe, make_fixnum (29));
+  /* (get '+-vertical-bar-backslash 'fringe) => 29 */
+
+  /* 30 */
+  DEFSYM (Qmc_pilcrow, "+-pilcrow");
+  Vfringe_bitmaps = Fcons (Qmc_pilcrow, Vfringe_bitmaps);
+  Fput (Qmc_pilcrow, Qfringe, make_fixnum (30));
+  /* (get '+-pilcrow 'fringe) => 30 */
+
+  /* 31 */
+  DEFSYM (Qmc_smiley_face, "+-smiley-face");
+  Vfringe_bitmaps = Fcons (Qmc_smiley_face, Vfringe_bitmaps);
+  Fput (Qmc_smiley_face, Qfringe, make_fixnum (31));
+  /* (get '+-smiley-face 'fringe) => 31 */
+
+  /* 32 */
+  DEFSYM (Qmc_single_angle_right, "+-single-angle-right");
+  Vfringe_bitmaps = Fcons (Qmc_single_angle_right, Vfringe_bitmaps);
+  Fput (Qmc_single_angle_right, Qfringe, make_fixnum (32));
+  /* (get '+-right-single-angle 'fringe) => 32 */
+
+  /* 33 */
+  DEFSYM (Qmc_single_angle_left, "+-single-angle-left");
+  Vfringe_bitmaps = Fcons (Qmc_single_angle_left, Vfringe_bitmaps);
+  Fput (Qmc_single_angle_left, Qfringe, make_fixnum (33));
+  /* (get '+-left-double-angle 'fringe) => 33 */
+
+  /* 34 */
+  DEFSYM (Qmc_double_angle_right, "+-double-angle-right");
+  Vfringe_bitmaps = Fcons (Qmc_double_angle_right, Vfringe_bitmaps);
+  Fput (Qmc_double_angle_right, Qfringe, make_fixnum (34));
+  /* (get '+-right-double-angle 'fringe) => 34 */
+
+  /* 35 */
+  DEFSYM (Qmc_double_angle_left, "+-double-angle-left");
+  Vfringe_bitmaps = Fcons (Qmc_double_angle_left, Vfringe_bitmaps);
+  Fput (Qmc_double_angle_left, Qfringe, make_fixnum (35));
+  /* (get '+-left-double-angle 'fringe) => 35 */
+
+  /* 36 */
+  DEFSYM (Qmc_triple_angle_right, "+-triple-angle-right");
+  Vfringe_bitmaps = Fcons (Qmc_triple_angle_right, Vfringe_bitmaps);
+  Fput (Qmc_triple_angle_right, Qfringe, make_fixnum (36));
+  /* (get '+-triple-angle-right 'fringe) => 36 */
+
+  /* 37 */
+  DEFSYM (Qmc_triple_angle_left, "+-triple-angle-left");
+  Vfringe_bitmaps = Fcons (Qmc_triple_angle_left, Vfringe_bitmaps);
+  Fput (Qmc_triple_angle_left, Qfringe, make_fixnum (37));
+  /* (get '+-triple-angle-left 'fringe) => 37 */
+
+  /* 38 */
+  DEFSYM (Qmc_single_angle_up, "+-single-angle-up");
+  Vfringe_bitmaps = Fcons (Qmc_single_angle_up, Vfringe_bitmaps);
+  Fput (Qmc_single_angle_up, Qfringe, make_fixnum (38));
+  /* (get '+-single-angle-up 'fringe) => 38 */
+
+  /* 39 */
+  DEFSYM (Qmc_single_angle_down, "+-single-angle-down");
+  Vfringe_bitmaps = Fcons (Qmc_single_angle_down, Vfringe_bitmaps);
+  Fput (Qmc_single_angle_down, Qfringe, make_fixnum (39));
+  /* (get '+-single-angle-down 'fringe) => 39 */
+
+  /* 40 */
+  DEFSYM (Qmc_double_angle_up, "+-double-angle-up");
+  Vfringe_bitmaps = Fcons (Qmc_double_angle_up, Vfringe_bitmaps);
+  Fput (Qmc_double_angle_up, Qfringe, make_fixnum (40));
+  /* (get '+-double-angle-up 'fringe) => 40 */
+
+  /* 41 */
+  DEFSYM (Qmc_double_angle_down, "+-double-angle-down");
+  Vfringe_bitmaps = Fcons (Qmc_double_angle_down, Vfringe_bitmaps);
+  Fput (Qmc_double_angle_down, Qfringe, make_fixnum (41));
+  /* (get '+-double-angle-down 'fringe) => 41 */
+
+  /* 42 */
+  DEFSYM (Qmc_triple_angle_up, "+-triple-angle-up");
+  Vfringe_bitmaps = Fcons (Qmc_triple_angle_up, Vfringe_bitmaps);
+  Fput (Qmc_triple_angle_up, Qfringe, make_fixnum (42));
+  /* (get '+-triple-angle-up 'fringe) => 42 */
+
+  /* 43 */
+  DEFSYM (Qmc_triple_angle_down, "+-triple-angle-down");
+  Vfringe_bitmaps = Fcons (Qmc_triple_angle_down, Vfringe_bitmaps);
+  Fput (Qmc_triple_angle_down, Qfringe, make_fixnum (43));
+  /* (get '+-triple-angle-down 'fringe) => 43 */
+
+  /* 44 */
+  DEFSYM (Qmc_quadruple_angle_up, "+-quadruple-angle-up");
+  Vfringe_bitmaps = Fcons (Qmc_quadruple_angle_up, Vfringe_bitmaps);
+  Fput (Qmc_quadruple_angle_up, Qfringe, make_fixnum (44));
+  /* (get '+-quadruple-angle-up 'fringe) => 44 */
+
+  /* 45 */
+  DEFSYM (Qmc_quadruple_angle_down, "+-quadruple-angle-down");
+  Vfringe_bitmaps = Fcons (Qmc_quadruple_angle_down, Vfringe_bitmaps);
+  Fput (Qmc_quadruple_angle_down, Qfringe, make_fixnum (45));
+  /* (get '+-quadruple-angle-down 'fringe) => 45 */
+
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
+
+
 }
 
 /* Garbage collection hook */
diff --git a/src/keyboard.c b/src/keyboard.c
index be727a6..0180d1a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1224,6 +1224,80 @@ static int read_key_sequence (Lisp_Object *, Lisp_Object,
                               bool, bool, bool, bool);
 static void adjust_point_for_property (ptrdiff_t, bool);
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+static void
+mc_switches_multiple_cursors (struct window *w, bool true_or_false_p)
+{
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p && BUFFERP (w->contents)
+      && (!NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf))
+          || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          || !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "\nmc_switches_multiple_cursors (%s):  %s\n",
+               window_char, true_or_false_p ? "true" : "false");
+    }
+#endif
+  w->mc.draw_multiple_cursors = true_or_false_p;
+  w->mc.erase_multiple_cursors = true_or_false_p;
+}
+
+static void
+mc_switches_crosshairs (struct window *w, bool true_or_false_p)
+{
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p && BUFFERP (w->contents)
+      && (!NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf))
+          || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          || !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "\nmc_switches_crosshairs (%s):  %s\n",
+               window_char, true_or_false_p ? "true" : "false");
+    }
+#endif
+  w->mc.draw_crosshairs = true_or_false_p;
+  w->mc.erase_crosshairs = true_or_false_p;
+  if (true_or_false_p)
+    w->must_be_updated_p = true;
+}
+
+static void
+mc_switches_fill_column (struct window *w, bool true_or_false_p)
+{
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p && BUFFERP (w->contents)
+      && (!NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf))
+          || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          || !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "\nmc_switches_fill_column (%s):  %s\n",
+               window_char, true_or_false_p ? "true" : "false");
+    }
+#endif
+  w->mc.draw_fill_column = true_or_false_p;
+  w->mc.erase_fill_column = true_or_false_p;
+  if (true_or_false_p)
+    w->must_be_updated_p = true;
+}
+
+/* *************************************************************************** */
+
+
 Lisp_Object
 command_loop_1 (void)
 {
@@ -1419,6 +1493,16 @@ command_loop_1 (void)
       Vreal_this_command = cmd;
       safe_run_hooks (Qpre_command_hook);
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      struct window *w = XWINDOW (selected_window);
+      mc_switches_multiple_cursors (w, true);
+
+/* *************************************************************************** */
+
+
       already_adjusted = 0;
 
       if (NILP (Vthis_command))
@@ -1565,6 +1649,18 @@ command_loop_1 (void)
       if (!NILP (KVAR (current_kboard, defining_kbd_macro))
 	  && NILP (KVAR (current_kboard, Vprefix_arg)))
 	finalize_kbd_macro_chars ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      mc_switches_multiple_cursors (w, false);
+      mc_switches_crosshairs (w, false);
+      mc_switches_fill_column (w, false);
+
+/* *************************************************************************** */
+
+
     }
 }
 
@@ -2448,7 +2544,15 @@ read_char (int commandflag, Lisp_Object map,
 	  if (help_echo_showing_p && !EQ (selected_window, minibuf_window))
 	    redisplay_preserve_echo_area (5);
 	  else
-	    redisplay ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+	    redisplay (1);
+
+/* *************************************************************************** */
+
 
 	  if (!input_pending)
 	    /* Normal case: no input arrived during redisplay.  */
@@ -2628,7 +2732,16 @@ read_char (int commandflag, Lisp_Object map,
     {
       Fdo_auto_save (auto_save_no_message ? Qt : Qnil, Qnil);
       /* Hooks can actually change some buffers in auto save.  */
-      redisplay ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      redisplay (2);
+
+/* *************************************************************************** */
+
+
     }
 
   /* Try reading using an X menu.
@@ -2692,7 +2805,16 @@ read_char (int commandflag, Lisp_Object map,
 	      && ! CONSP (Vunread_command_events))
 	    {
 	      Fdo_auto_save (auto_save_no_message ? Qt : Qnil, Qnil);
-	      redisplay ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+	      redisplay (3);
+
+/* *************************************************************************** */
+
+
 	    }
 	}
 
@@ -2795,7 +2917,15 @@ read_char (int commandflag, Lisp_Object map,
     {
       if (commandflag >= 0
 	  && !input_pending && !detect_input_pending_run_timers (0))
-	redisplay ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+	redisplay (4);
+
+/* *************************************************************************** */
+
 
       goto wrong_kboard;
     }
@@ -3093,7 +3223,15 @@ read_char (int commandflag, Lisp_Object map,
       /* Remove the help from the frame.  */
       unbind_to (count, Qnil);
 
-      redisplay ();
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      redisplay (5);
+
+/* *************************************************************************** */
+
+
       if (EQ (c, make_fixnum (040)))
 	{
 	  cancel_echoing ();
diff --git a/src/lisp.h b/src/lisp.h
index 7e7dba6..46d9231 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3579,7 +3579,15 @@ extern void message_with_string (const char *, Lisp_Object, bool);
 extern void message_log_maybe_newline (void);
 extern void update_echo_area (void);
 extern void truncate_echo_area (ptrdiff_t);
-extern void redisplay (void);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+extern void redisplay (int);
+
+/* *************************************************************************** */
+
 
 void set_frame_cursor_types (struct frame *, Lisp_Object);
 extern void syms_of_xdisp (void);
diff --git a/src/nsterm.m b/src/nsterm.m
index bcc23ff..eb7b72b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -278,6 +278,9 @@ - (NSColor *)colorUsingDefaultColorSpace
 long context_menu_value = 0;
 
 /* display update */
+static struct frame *ns_updating_frame;
+static NSView *focus_view = NULL;
+static BOOL gsaved = NO;
 static int ns_window_num = 0;
 static BOOL ns_fake_keydown = NO;
 #ifdef NS_IMPL_COCOA
@@ -1087,6 +1090,16 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
    external (RIF) call; whole frame, called before update_window_begin
    -------------------------------------------------------------------------- */
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = f;
+
+/* *************************************************************************** */
+
+
 #ifdef NS_IMPL_COCOA
   EmacsView *view = FRAME_NS_VIEW (f);
 
@@ -1103,6 +1116,9 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
       [toolbar setVisible: tbar_visible];
   }
 
+  ns_updating_frame = f;
+  [view lockFocus];
+
   /* drawRect may have been called for say the minibuffer, and then clip path
      is for the minibuffer.  But the display engine may draw more because
      we have set the frame as garbaged.  So reset clip path to the whole
@@ -1206,12 +1222,31 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
    external (RIF) call; for whole frame, called after update_window_end
    -------------------------------------------------------------------------- */
 {
+  EmacsView *view = FRAME_NS_VIEW (f);
+
   NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
 
 /*   if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
   MOUSE_HL_INFO (f)->mouse_face_defer = 0;
-}
 
+  block_input ();
+
+  [view unlockFocus];
+  [[view window] flushWindow];
+
+  unblock_input ();
+  ns_updating_frame = NULL;
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = NULL;
+
+/* *************************************************************************** */
+
+
+}
 
 static BOOL
 ns_clip_to_rect (struct frame *f, NSRect *r, int n)
@@ -1226,23 +1261,31 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
     {
       NSTRACE_RECT ("r", *r);
 
-      if ([NSView focusView] == FRAME_NS_VIEW (f))
-        {
-          [[NSGraphicsContext currentContext] saveGraphicsState];
-          if (n == 2)
-            NSRectClipList (r, 2);
-          else
-            NSRectClip (*r);
-
-          return YES;
-        }
-      else
+      if (f != ns_updating_frame)
         {
           NSView *view = FRAME_NS_VIEW (f);
-          int i;
-          for (i = 0 ; i < n ; i++)
-            [view setNeedsDisplayInRect:r[i]];
+          if (view != focus_view)
+            {
+              if (focus_view != NULL)
+                {
+                  [focus_view unlockFocus];
+                  [[focus_view window] flushWindow];
+              /* debug_lock--; */
+              return YES;
+                }
+              if (view)
+                [view lockFocus];
+              focus_view = view;
+              /* if (view) debug_lock++; */
+            }
         }
+      [[NSGraphicsContext currentContext] saveGraphicsState];
+      if (n == 2)
+        NSRectClipList (r, 2);
+      else
+        NSRectClip (*r);
+      gsaved = YES;
+      return YES;
     }
 
   return NO;
@@ -1256,7 +1299,22 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
 {
   NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
 
-  [[NSGraphicsContext currentContext] restoreGraphicsState];
+  if (gsaved)
+    {
+      [[NSGraphicsContext currentContext] restoreGraphicsState];
+      gsaved = NO;
+    }
+
+  if (f != ns_updating_frame)
+    {
+      if (focus_view != NULL)
+        {
+          [focus_view unlockFocus];
+          [[focus_view window] flushWindow];
+          focus_view = NULL;
+/* debug_lock--; */
+        }
+    }
 }
 
 
@@ -3210,56 +3268,178 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
       h = cursor_height;
     }
 
-  r.origin.x = fx, r.origin.y = fy;
-  r.size.height = h;
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  r.origin.x = (w->mc.fx > 0)
+               ? w->mc.fx
+               : fx;
+  r.origin.y = (w->mc.fy > 0)
+               ? w->mc.fy
+               : fy;
+  r.size.height = (w->mc.h > 0)
+                  ? w->mc.h
+                  : h;
   r.size.width = w->phys_cursor_width;
 
+/* *************************************************************************** */
+
+
   /* Prevent the cursor from being drawn outside the text area.  */
   if (ns_clip_to_row (w, glyph_row, TEXT_AREA, NO))
     {
       face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
-      if (face && NS_FACE_BACKGROUND (face)
-          == ns_index_color (FRAME_CURSOR_COLOR (f), f))
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
+
+/* EXAMPLE OF HOW TO LOOK-UP A COLOR:
+  enum face_id face_id = lookup_named_face (w, f, intern ("+-vertical-bar-face"), true);
+  struct face *face = FACE_FROM_ID (f, face_id);
+  NSColor *color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f);
+
+  EXAMPLE OF HOW TO PRINT A COLOR TO STDERR:
+  Lisp_Object foreground = face->lface[LFACE_FOREGROUND_INDEX];
+  Lisp_Object background = face->lface[LFACE_BACKGROUND_INDEX];
+  fprintf (stderr, "\nforeground (%s) | background (%s)\n",
+                   (!NILP (foreground) ? SSDATA (foreground) : "NILP"),
+                   (!NILP (background) ? SSDATA (background) : "NILP"));
+
+  EXAMPLE OF HOW TO CREATE A COLOR WITH RGB/LSL float values:
+  NSColor *my_color = [NSColor colorWithCalibratedRed: s->w->mc.red
+                                                green: s->w->mc.green
+                                                 blue: s->w->mc.blue
+                                                alpha: 1.0]; */
+
+  if (w->mc.glyph_flavor == MC_GLYPH
+      || w->mc.glyph_flavor == MC_GLYPHLESS
+      || w->mc.glyph_flavor == MC_GLYPH_TAB)
+    {
+      [[NSColor colorWithCalibratedRed: w->mc.red green: w->mc.green blue: w->mc.blue alpha: 1.0] set];
+      Lisp_Object buf = w->contents;
+      CHECK_BUFFER (buf);
+      struct buffer *b = XBUFFER (buf);
+      bool region_active_p = (!NILP (Vtransient_mark_mode)
+                              && !NILP (BVAR (b, mark_active)));
+      ptrdiff_t region_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+      ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+      bool region_in_bounds_p = (region_active_p
+                                 && w->mc.posint >= region_beginning
+                                 && w->mc.posint < region_end);
+      if (region_active_p
+          && region_in_bounds_p
+          && active_p)
         {
-          [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
-          hollow_color = FRAME_CURSOR_COLOR (f);
+          enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+          struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+          NSColor *hollow_active_region_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_region_face), f);
+          hollow_color = hollow_active_region_color;
         }
+        else if (region_active_p
+                 && !region_in_bounds_p
+                 && active_p)
+          {
+            enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+            struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+            NSColor *hollow_active_region_out_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_out_face), f);
+            hollow_color = hollow_active_region_out_color;
+          }
+          else if (!region_active_p && active_p)
+            {
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+              struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+              NSColor *hollow_active_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_face), f);
+              hollow_color = hollow_active_color;
+            }
+            /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+            else if (!active_p)
+              {
+                enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                NSColor *hollow_inactive_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_inactive_face), f);
+                hollow_color = hollow_inactive_color;
+              }
+              else if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (f), f))
+                hollow_color = FRAME_CURSOR_COLOR (f);
+                else
+                  {
+                    struct face *default_bg_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+                    [ns_lookup_indexed_color (NS_FACE_BACKGROUND (default_bg_face), f) set];
+                    hollow_color = FRAME_CURSOR_COLOR (f);
+                  }
+    }
+    else if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (f), f))
+      {
+        [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
+        hollow_color = FRAME_CURSOR_COLOR (f);
+      }
       else
         [FRAME_CURSOR_COLOR (f) set];
 
-      switch (cursor_type)
-        {
-        case DEFAULT_CURSOR:
-        case NO_CURSOR:
-          break;
-        case FILLED_BOX_CURSOR:
-          NSRectFill (r);
-          break;
-        case HOLLOW_BOX_CURSOR:
-          NSRectFill (r);
-          [hollow_color set];
-          NSRectFill (NSInsetRect (r, 1, 1));
-          [FRAME_CURSOR_COLOR (f) set];
-          break;
-        case HBAR_CURSOR:
-          NSRectFill (r);
-          break;
-        case BAR_CURSOR:
-          s = r;
-          /* If the character under cursor is R2L, draw the bar cursor
-             on the right of its glyph, rather than on the left.  */
-          cursor_glyph = get_phys_cursor_glyph (w);
-          if ((cursor_glyph->resolved_level & 1) != 0)
-            s.origin.x += cursor_glyph->pixel_width - s.size.width;
-
-          NSRectFill (s);
-          break;
-        }
-      ns_reset_clipping (f);
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
+
+
+  switch (cursor_type)
+    {
+    case DEFAULT_CURSOR:
+    case NO_CURSOR:
+      break;
+    case FILLED_BOX_CURSOR:
+      NSRectFill (r);
+      break;
+    case HOLLOW_BOX_CURSOR:
+      NSRectFill (r);
+      [hollow_color set];
+      NSRectFill (NSInsetRect (r, 1, 1));
+      [FRAME_CURSOR_COLOR (f) set];
+      break;
+    case HBAR_CURSOR:
+      NSRectFill (r);
+      break;
+    case BAR_CURSOR:
+      s = r;
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    /* @lawlist is focusing the initial development of feature requests #17684
+    and #22873 on L2R languages. */
+    if (w->mc.glyph_flavor != MC_GLYPH
+        && w->mc.glyph_flavor != MC_GLYPHLESS
+        && w->mc.glyph_flavor != MC_GLYPH_TAB)
+      {
+      /* If the character under cursor is R2L, draw the bar cursor
+         on the right of its glyph, rather than on the left.  */
+      cursor_glyph = get_phys_cursor_glyph (w);
+      if ((cursor_glyph->resolved_level & 1) != 0)
+        s.origin.x += cursor_glyph->pixel_width - s.size.width;
+      }
+
+/* *************************************************************************** */
+
+
+      NSRectFill (s);
+      break;
+    }
+  ns_reset_clipping (f);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  /* draw the character under the cursor */
+  if (cursor_type != NO_CURSOR
+      && w->mc.glyph_flavor != MC_GLYPHLESS
+      && w->mc.glyph_flavor != MC_GLYPH_TAB)
+    draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+
+/* *************************************************************************** */
+
 
-      /* draw the character under the cursor */
-      if (cursor_type != NO_CURSOR)
-        draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
     }
 }
 
@@ -3926,7 +4106,27 @@ Function modeled after x_draw_glyph_string_box ().
     {
       int thickness = abs (s->img->relief);
       if (thickness == 0) thickness = 1;
-      ns_draw_box (br, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    if (s->w->mc.glyph_flavor == MC_GLYPH
+        || s->w->mc.glyph_flavor == MC_GLYPHLESS
+        || s->w->mc.glyph_flavor == MC_GLYPH_TAB)
+      {
+        NSColor *border_color = [NSColor colorWithCalibratedRed: s->w->mc.red
+                                                          green: s->w->mc.green
+                                                           blue: s->w->mc.blue
+                                                          alpha: 1.0];
+        ns_draw_box (br, thickness, border_color, 1, 1);
+      }
+      else
+        ns_draw_box (br, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
+
+/* *************************************************************************** */
+
+
     }
 }
 
diff --git a/src/w32term.c b/src/w32term.c
index 8d189ae..e7fb8a3 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -545,6 +545,15 @@ x_update_begin (struct frame *f)
   if (! FRAME_W32_P (f))
     return;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = f;
+
+/* *************************************************************************** */
+
+
   /* Regenerate display palette before drawing if list of requested
      colors has changed. */
   if (display_info->regen_palette)
@@ -754,6 +763,16 @@ x_update_end (struct frame *f)
 
   /* Mouse highlight may be displayed again.  */
   MOUSE_HL_INFO (f)->mouse_face_defer = false;
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = NULL;
+
+/* *************************************************************************** */
+
+
 }
 
 
@@ -973,6 +992,20 @@ static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
 static void
 x_set_cursor_gc (struct glyph_string *s)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  if (s->w->mc.cursor_gc_default)
+    {
+      s->gc = s->f->output_data.w32->cursor_gc;
+      return;
+    }
+
+/* *************************************************************************** */
+
+
   if (s->font == FRAME_FONT (s->f)
       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
@@ -5690,6 +5723,26 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 
   /* Compute frame-relative coordinates for phys cursor.  */
   get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* LEGEND:
+
+-  top y == WINDOW_TO_FRAME_PIXEL_Y (w, row->y)
+
+-  bottom y == WINDOW_TO_FRAME_PIXEL_Y (w, row->y) - row->height
+
+-  h of HOLLOW_BOX_CURSOR == row->height
+   [This avoids a visible gap above/below.] */
+
+  if (w->mc.h > 0)
+    h = row->height;
+
+/* *************************************************************************** */
+
+
   rect.left = left;
   /* When on R2L character, show cursor at the right edge of the
      glyph, unless the cursor box is as wide as the glyph or wider
@@ -5753,7 +5806,17 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
 	 invisible.  Use the glyph's foreground color instead in this
 	 case, on the assumption that the glyph's colors are chosen so
 	 that the glyph is legible.  */
-      if (face->background == cursor_color)
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      if (face->background == cursor_color
+          && !w->mc.cursor_gc_invisible_okay)
+
+/* *************************************************************************** */
+
+
 	cursor_color = face->foreground;
 
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
@@ -5774,6 +5837,17 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
 	  if ((cursor_glyph->resolved_level & 1) != 0)
 	    x += cursor_glyph->pixel_width - width;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    /* Align all fake BAR_CURSOR of the VERTICAL_RULER with `opoint_x'. */
+    if (w->mc.fx > 0)
+      x = w->mc.fx;
+
+/* *************************************************************************** */
+
+
 	  w32_fill_area (f, hdc, cursor_color, x,
 			 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
 			 width, row->height);
@@ -5895,31 +5969,169 @@ 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;
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
 
-	case BAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
-	  break;
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  COLORREF original_cursor_pixel = f->output_data.w32->cursor_pixel;
+  /* xterm.c/xterm.h use GC; whereas, w32term.c/w32term.h use XGCValues * */
+  XGCValues *original_cursor_gc = f->output_data.w32->cursor_gc;
+  double base = 255.0;
+  double term_red = base * w->mc.red;
+  double term_green = base * w->mc.green;
+  double term_blue = base * w->mc.blue;
+  int int_red = XFIXNUM (Ftruncate (make_float (term_red), Qnil));
+  int int_green = XFIXNUM (Ftruncate (make_float (term_green), Qnil));;
+  int int_blue = XFIXNUM (Ftruncate (make_float (term_blue), Qnil));;
+  COLORREF color_pixel = PALETTERGB (int_red, int_green, int_blue);
+  switch (cursor_type)
+  {
+    case HOLLOW_BOX_CURSOR:
+    {
+      struct glyph *glyph = get_phys_cursor_glyph (w);
+      if (glyph == NULL)
+        return;
+      if (glyph->type != IMAGE_GLYPH && w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          XGCValues gc_values;
+          unsigned long mask = GCFont | GCForeground | GCBackground;
+          gc_values.font = FRAME_FONT (f);
+          struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+          Lisp_Object buf = w->contents;
+          CHECK_BUFFER (buf);
+          struct buffer *b = XBUFFER (buf);
+          bool region_active_p = (!NILP (Vtransient_mark_mode)
+                                  && !NILP (BVAR (b, mark_active)));
+          ptrdiff_t region_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+          ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+          bool region_in_bounds_p = (region_active_p
+                                     && w->mc.posint >= region_beginning
+                                     && w->mc.posint < region_end);
+          /* Temporarily hijack `f->output_data.w32->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in w32fns.c.  */
+          if (region_active_p
+              && region_in_bounds_p
+              && active_p)
+            {
+              enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+              struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+              gc_values.foreground = default_face->foreground;
+              gc_values.background = hollow_active_region_face->background;
+            }
+            else if (region_active_p
+                     && !region_in_bounds_p
+                     && active_p)
+              {
+                enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                gc_values.foreground = default_face->foreground;
+                gc_values.background = hollow_active_region_out_face->foreground;
+              }
+              else if (!region_active_p && active_p)
+                {
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  gc_values.foreground = default_face->foreground;
+                  gc_values.background = hollow_active_face->background;
+                }
+                /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                else if (!active_p)
+                  {
+                    enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                    struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                    gc_values.foreground = default_face->foreground;
+                    gc_values.background = hollow_inactive_face->background;
+                  }
+          f->output_data.w32->cursor_gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &gc_values);
+          block_input ();
+          /* Force `x_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'.  */
+          w->mc.cursor_gc_default = true;
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+          w->mc.cursor_gc_default = false;
+          f->output_data.w32->cursor_gc = original_cursor_gc;
+          unblock_input ();
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          x_draw_hollow_cursor (w, glyph_row);
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else if (glyph->type == IMAGE_GLYPH && w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+          {
+            /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+            f->output_data.w32->cursor_pixel = color_pixel;
+            x_draw_hollow_cursor (w, glyph_row);
+            f->output_data.w32->cursor_pixel = original_cursor_pixel;
+          }
+          else
+            x_draw_hollow_cursor (w, glyph_row);
+      break;
+    }
+    case FILLED_BOX_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in w32fns.c.  */
+          block_input ();
+          XGCValues gc_values;
+          unsigned long mask = GCFont | GCForeground | GCBackground;
+          gc_values.font = FRAME_FONT (f);
+          gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
+          gc_values.background = color_pixel;
+          f->output_data.w32->cursor_gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &gc_values);
+          /* Force `x_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'.  */
+          w->mc.cursor_gc_default = true;
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+          w->mc.cursor_gc_default = false;
+          f->output_data.w32->cursor_gc = original_cursor_gc;
+          unblock_input ();
+        }
+        else
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+      break;
+    }
+    case BAR_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          w->mc.cursor_gc_invisible_okay = true;
+          x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+          w->mc.cursor_gc_invisible_okay = false;
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+      break;
+    }
+    case HBAR_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          w->mc.cursor_gc_invisible_okay = true;
+          x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+          w->mc.cursor_gc_invisible_okay = false;
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        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 ();
+  }
 
-	case HBAR_CURSOR:
-	  x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
-	  break;
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
 
-	case NO_CURSOR:
-	  w->phys_cursor_width = 0;
-	  break;
 
-	default:
-	  emacs_abort ();
-	}
     }
 }
 
diff --git a/src/window.h b/src/window.h
index cc0b6b6..40f8a85 100644
--- a/src/window.h
+++ b/src/window.h
@@ -76,6 +76,62 @@ one and the same, so its prev and next members are nil.
 
 A dead window has its contents field set to nil.  */
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
+
+/* Suffixes for the `mc` window pointer prefix. */
+struct multiple_cursors
+{
+  /* Values for previous and current `window-start' and `window-end'. */
+  EMACS_INT current_start, current_end, previous_start, previous_end, current_x, previous_x;
+
+  /* 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 cursor_gc_default : 1;
+
+  /* True means `x_set_cursor_gc' should permit the foreground and background
+  colors to be the same.  The default behavior disallows an invisible result. */
+  bool_bf cursor_gc_invisible_okay : 1;
+
+  /* True means `mc_draw_multiple_cursors' has not run yet drawn glyph fake cursors. */
+  bool_bf draw_multiple_cursors : 1;
+
+  /* True means `mc_erase_multiple_cursors' has not run yet erased glyph fake cursors. */
+  bool_bf erase_multiple_cursors : 1;
+
+  /* True means crosshairs have not yet been drawn. */
+  bool_bf draw_crosshairs : 1;
+
+  /* True means crosshairs have not yet been erased. */
+  bool_bf erase_crosshairs : 1;
+
+  /* The flavor of the glyph used by `draw_window_cursor'. */
+  int glyph_flavor;
+
+  /* L.S.L. colors. */
+  double red, green, blue;
+
+  /* The buffer position point of a fake cursor. */
+  int posint;
+
+  /* Pixel position (window relative) of horizontal/vertical rulers. */
+  int fx, fy, h;
+
+  /* Record FROM_WHERE when `redisplay_preserve_echo_area' is called. */
+  int redisplay_preserve_echo_area;
+
+  /* True means the visible fill column has not yet been drawn. */
+  bool_bf draw_fill_column : 1;
+
+  /* True means the visible fill column has not yet been erased. */
+  bool_bf erase_fill_column : 1;
+};
+
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
+
+
 struct cursor_pos
 {
   /* Pixel position.  These are always window relative.  */
@@ -181,6 +237,28 @@ struct window
     /* The help echo text for this window.  Qnil if there's none.  */
     Lisp_Object mode_line_help_echo;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    /* The cache for multiple glyph cursors.  For an example of the structure of
+    the list, see the comments at the beginning of `mc_draw_multiple_cursors' in
+    xdisp.c.  */
+    Lisp_Object multiple_cursors_cache;
+
+    /* The cache for multiple glyph/glyphless cursors that form crosshairs.  For an
+    example of the structure of the list, see the comments at the beginning of
+    `mc_draw_multiple_cursors' in xdisp.c.  */
+    Lisp_Object crosshairs_cache;
+
+    /* The cache for multiple glyph/glyphless cursors that form the visible fill
+    column.  For an example of the structure of the list, see the comments at the
+    beginning of `mc_draw_multiple_cursors' in xdisp.c.  */
+    Lisp_Object mc_fill_column_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.  */
@@ -283,6 +361,16 @@ struct window
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    /* 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;
 
@@ -421,6 +509,31 @@ XWINDOW (Lisp_Object a)
   return XUNTAG (a, Lisp_Vectorlike, struct window);
 }
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+INLINE void
+wset_multiple_cursors_cache (struct window *w, Lisp_Object val)
+{
+  w->multiple_cursors_cache = val;
+}
+
+INLINE void
+wset_crosshairs_cache (struct window *w, Lisp_Object val)
+{
+  w->crosshairs_cache = val;
+}
+
+INLINE void
+wset_mc_fill_column_cache (struct window *w, Lisp_Object val)
+{
+  w->mc_fill_column_cache = val;
+}
+
+/* *************************************************************************** */
+
+
 /* Most code should use these functions to set Lisp fields in struct
    window.  */
 INLINE void
diff --git a/src/xdisp.c b/src/xdisp.c
index fa7691c..aecf3e4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -830,7 +830,16 @@ static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
 static void push_it (struct it *, struct text_pos *);
 static void iterate_out_of_display_property (struct it *);
 static void pop_it (struct it *);
-static void redisplay_internal (void);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+static void redisplay_internal (int);
+
+/* *************************************************************************** */
+
+
 static void echo_area_display (bool);
 static void block_buffer_flips (void);
 static void unblock_buffer_flips (void);
@@ -921,6 +930,5100 @@ static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
 static bool coords_in_mouse_face_p (struct window *, int, int);
 
 
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
+
+/* MULTIPLE CURSORS:  Emacs Bug #22873 (feature request)
+
+   CROSSHAIRS:  Emacs Bug #17684 (feature request)
+
+
+PATCH VERSION:  014.000 [08/28/2018]
+                014.001 [09/01/2018]
+                014.002 [09/02/2018]
+                014.003 [09/05/2018]
+                014.004 [09/08/2018]
+                014.005 [09/09/2018]
+                014.006 [09/09/2018]
+                014.007 [09/10/2018]
+                014.008 [09/10/2018]
+                014.009 [09/11/2018]
+                014.010 [09/13/2018]
+                014.011 [09/14/2018]
+                014.012 [09/17/2018]
+                014.013 [09/18/2018]
+                014.014 [09/19/2018]
+                014.015 [09/23/2018]
+                014.016 [09/24/2018]
+                014.017 [09/25/2018]
+                014.018 [09/26/2018]
+                014.019 [10/01/2018]
+                014.020 [10/02/2018]
+                014.021 [10/09/2018]
+                014.022 [10/10/2018]
+                014.023 [10/10/2018]
+                014.024 [10/13/2018]
+                014.025 [11/10/2018]
+                015.000 [11/10/2018]
+                015.001 [11/11/2018]
+                016.000 [11/20/2018]
+
+Apply patch to master branch:  Sat Jul 7 09:59:53 2018 -0700
+git reset --hard 98463bed07ecc9057094928ffdc2321eaaf3ab52
+
+Last Commit : Sat Jul 7 09:59:53 2018 -0700
+            : Glenn Morris <rgm@gnu.org>
+            : 98463bed07ecc9057094928ffdc2321eaaf3ab52
+            : * lisp/imenu.el: Require cl-lib, not internal components of same.
+
+
+SETUP:
+
+Step 1:  git clone -b master git://git.sv.gnu.org/emacs.git
+
+Step 2:  In the new emacs folder, go back to an Emacs version from 11/16/2018:
+
+git reset --hard 644a308b4e1513e04be9360e1586e14b32ec0159
+
+Step 3:  From within the new emacs folder created in Step 1, apply the patch:
+
+git apply /path/to/the/attached.diff
+
+[There should not be any error messages at this point; i.e, you should be returned to a new command prompt.]
+
+Step 4:  ./autogen.sh
+
+Step 5:  ./configure ... [your custom options]
+
+Step 6:  make
+
+Step 7:  make install
+
+-  To try out built-in fake cursors with Magnar Sveen's library (multiple-cursors), install that package first.  [If the multiple-cursors package is installed, an eval-after-load "multiple-cursors-core" statement within crosshairs.el will redefine a couple of functions and set up a few keyboard shortcuts.]  If the multiple-cursors package by Magnar Sveen is not already installed, then there are two easy ways to install that package:
+
+   Type:  M-x mc-install
+
+   OR, evaluate the following snippet:
+
+  (progn
+    (require 'package)
+    (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
+    (package-initialize)
+    (package-refresh-contents)
+    (package-install 'multiple-cursors))
+
+-  To try out crosshairs and the visible fill column, type:  M-x +-mode
+
+-  To try out only the visible fill column, type:  M-x mc-fill-column-mode
+
+-  To learn how to use the multiple fake cursors feature, examine the
+   interactive function `mc-test'.
+
+-  EXAMPLE OF HOW TO USE MULTIPLE FAKE CURSORS:
+
+  ;;; (BUFFER-POSITION CURSOR-TYPE CURSOR-COLOR)
+  ;;;
+  (setq multiple-cursors-conf '((1 "hbar" "magenta")
+                                (2 "bar" "purple")
+                                (3 "box" "#00FF00")
+                                (4 "hollow" "#0000FF")
+                                (5 ("hbar" 3) [1.0 0.0 1.0])
+                                (6 ("bar" 3) [0.0 1.0 1.0])))
+
+  ;;; TURN OFF.
+  ;;;
+  (setq multiple-cursors-conf nil)
+
+
+CHANGELOG:
+
+-  The area of code that prevented crosshairs and other fake cursors from
+   working on MacOS Mojave has been fixed.
+
+-  New Feature:  This is the first implementation of a visible fill column
+   using fake cursors, which has similar abilities to crosshairs; e.g.,
+   draw forthwith whenever the real cursor gets drawn; draw on an idle
+   timer; fill column indicator in inactive/active windows have different
+   colors; suppress display of fill column indicator in inactive windows
+   (if so desired); color of the fill column indicator in active/inactive
+   windows is a different color when the cursor is lined up with the fill
+   column and crosshairs is active.  Crosshairs incorporates the fill
+   column indicator if the variable `+-fill-column' is non-nil; or, there
+   is a separate minor-mode called `mc-fill-column-mode' (if so desired).
+
+-  Floating horizontal ruler now increments by glyph->pixel_width instead
+   of frame-char-width.  [This avoids visible gaps.]
+
+-  Multiple fake cursors can now be placed at the end of a line when there
+   is no `buffer-display-table' entry for a visible EOL glyph.
+
+-  Crosshairs now use the line height instead of the glyph height.  [This
+   avoids visible gaps in the vertical ruler of crosshairs.]
+
+-  The border color for images with a fake cursor now match the fake
+   cursor color.
+
+-  With the gracious assistance of Eli Z., a test now exists for the situation
+   when `draw_glyphs' redraws a tab stretch due to a subsequent character
+   with a left overhang.  Additional work needs to be done ... [infra].
+
+-  Only call `update_begin' / `update_end' when the frame was not already
+   in the process of being updated.
+
+-  Miscellaneous bug fixes.
+
+
+TODO:
+
+-  Crosshairs in the inactive windows is causing cursors in the active
+   windows to be erased (when the active window drew prior thereto).
+
+-  Face of tab stretch gets extended to window edge on NS, but not on X11
+   or NT platforms:
+   https://lists.gnu.org/archive/html/emacs-devel/2018-11/msg00316.html
+
+-  Continue working on the section of code within `draw_glyphs' that is
+   responsible for redrawing a stretch tab (erasing a fake cursor) when the next
+   character has a left overhang.  "	A".  A temporary fix has been instituted
+   that simply bypasses the section of code at issue; however, the optimal
+   solution will be to let `draw_glyphs' do its thing and then redraw the
+   fake cursors along the stretch tab subsequent thereto.
+
+-  Multiple Cursors:  If point is in the middle of a composite character, then
+   select a fully composed character so that the fake cursor is visible.
+
+-  Fake cursors are being redrawn too often when non-selected visible windows
+   have an ongoing process that require frequent redisplay updates (e.g.,
+   an eshell buffer.  @lawlist may have already corrected the frequent redisplay
+   issue as to mouse-overs, but will need to check this once again to be sure.
+
+-  Set up some tests to see what (if anything) needs to be done so that
+   these features play nicely with certain overlays and text properties.
+
+-  Implement functionality similar to the multiple-cursors library by Magnar Sveen.
+
+-  Create a comprehensive list of items to test when modifying these features; and,
+   add a test file.
+
+-  Follow up with the Emacs team re bug#32177; i.e., (Current line number shifts
+   one column to the left.)
+
+-  Follow up with the Emacs team re bug#32060; i.e., (Horizontal Scrolling
+   (Current Line):  Wrong line gets h-scrolled.)
+
+-  Determine if bug #28936 needs to be fixed and help the Emacs team re same.
+
+
+TESTING:  Situations that always need to be tested when working on these features.
+
+-  Multiple Fake Cursors:  Line endings.
+
+-  Crosshairs:  Line endings.
+
+-  it->line_wrap == TRUNCATE
+
+-  it->line_wrap == WORD_WRAP
+
+-  it->line_wrap == WINDOW_WRAP
+
+-  Horizontal Scrolling -- Temporary:  (scroll-left 1)
+
+   (setq-local auto-hscroll-mode 'current-line)
+
+-  Horizontal Scrolling -- Permanent:  (scroll-left 1 t)
+
+   (setq-local auto-hscroll-mode 'current-line)
+
+-  (fundamental-mode)
+   (setq display-line-numbers t)
+   (setq buffer-display-table (make-display-table))
+   (aset buffer-display-table
+         ?\t
+         (vector (make-glyph-code ?\u00BB 'font-lock-warning-face)
+                 (make-glyph-code ?\t 'highlight)))
+   (aset buffer-display-table
+         ?\n
+         (vector (make-glyph-code ?\u00B6 'font-lock-comment-face)
+                 ?\n))
+   (setq tab-width 8)
+   (setq-local auto-hscroll-mode 'current-line)
+
+-  No Line Numbers
+
+
+CREATION OF REPOSITORY:
+
+  mkdir DIRECTORY
+
+  cd DIRECTORY
+
+  git init
+
+  git remote add origin https://github.com/lawlist/17684_22873.git
+
+  ### Have a look at the current configuration.
+  ###   origin https://github.com/lawlist/17684_22873.git (fetch)
+  ###   origin https://github.com/lawlist/17684_22873.git (push)
+  git remote -v
+
+  git remote add upstream https://git.savannah.gnu.org/git/emacs.git
+
+  ### Verify the new configuration.
+  ###   origin https://github.com/lawlist/17684_22873.git (fetch)
+  ###   origin https://github.com/lawlist/17684_22873.git (push)
+  ###   upstream https://git.savannah.gnu.org/git/emacs.git (fetch)
+  ###   upstream https://git.savannah.gnu.org/git/emacs.git (push)
+  git remote -v
+
+  git fetch upstream
+
+  ### Create a new branch `17684_22873` so you don't have to override the upstream `master`.
+  git checkout -b 17684_22873 98463bed07ecc9057094928ffdc2321eaaf3ab52
+
+  ### Create the online Github repository if not already in existence.
+  curl -u USERNAME:PASSWORD https://api.github.com/user/repos -d '{"name":"17684_22873.git"}'
+
+  git push -u origin 17684_22873
+
+  ### Apply the following patch:  014.000 [08/28/2018]
+  ### add/commit/push
+
+  ### Apply the following patch:  014.001 [09/01/2018]
+  ### add/commit/push
+
+  ### Apply the following patch:  014.002 [09/02/2018]
+  ### add/commit/push
+
+
+UPDATE THE REPOSITORY:
+
+  git apply /path/to/the/emacs/patch.diff
+  git add .
+  git commit -m "INSERT COMMIT MESSAGE."
+  git push -u origin 17684_22873
+
+CREATE PATCHES:  git format-patch -1 SHA
+                 git format-patch -1 -o /path/to/output/directory SHA
+
+LEGEND:
+
+make_number => make_fixnum
+
+XINT => XFIXNUM
+
+RANGED_INTEGERP => RANGED_FIXNUMP
+
+TYPE_RANGED_INTEGERP => TYPE_RANGED_FIXNUMP
+
+XFASTINT => XFIXNAT
+
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p && BUFFERP (w->contents)
+      && (!NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf))
+          || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          || !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "\nwindow (%s)\n", window_char);
+    }
+#endif
+
+#ifdef GLYPH_DEBUG
+  struct frame *f = XFRAME (w->frame);
+  int temp_fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+  int temp_fy = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+  enum window_part part = ON_NOTHING;
+  Lisp_Object window = window_from_coordinates (f, temp_fx, temp_fy, &part, false);
+  Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+  debug_method_add (w, "window (%s)", SSDATA (window_string));
+#endif
+
+char *w_contents = (BUFFERP (w->contents) && STRINGP (BVAR (XBUFFER (w->contents), name)))
+                   ? SSDATA (BVAR (XBUFFER (w->contents), name))
+                   : "nil";
+fprintf (stderr, "\nBuffer (%s)\n", w_contents);
+
+struct face *face = mc_lookup_face (it);
+Lisp_Object foreground = face->lface[LFACE_FOREGROUND_INDEX];
+Lisp_Object background = face->lface[LFACE_BACKGROUND_INDEX];
+fprintf (stderr, "\nforeground (%s) | background (%s)\n",
+                 (!NILP (foreground) ? SSDATA (foreground) : "NILP"),
+                 (!NILP (background) ? SSDATA (background) : "NILP"));
+
+fprintf (stderr, "My lisp object:  %s\n", SSDATA (Fchar_to_string (make_fixnum (101))));
+
+fprintf (stderr, "string: %s | int: %d\n", SSDATA (build_string ("foo")), 69);
+
+if (BUFFERP (w->contents) && STRINGP (BVAR (XBUFFER (w->contents), name)))
+  fprintf (stderr, "ns_update_window_end:  %s\n", SSDATA (BVAR (XBUFFER (w->contents), name)));
+
+AUTO_STRING (my_string_one, "This is the value of `my_object_one':  %s");
+Lisp_Object my_object_one = make_float (0.1);
+CALLN (Fmessage, my_string_one, my_object_one);
+
+AUTO_STRING (my_string_two, "This is the value of `my_object_two':  %s");
+Lisp_Object my_object_two = make_fixnum (777);
+CALLN (Fmessage, my_string_two, my_object_two);
+
+WINDOW:  w->contents
+
+BUFFER:  XBUFFER (w->contents)
+
+BUFFER LOCAL VARIABLE:  BVAR (XBUFFER (w->contents), variable_name)
+
+NO NARROWING:
+
+BEG == Beginning of Buffer (window displays current buffer)
+
+ZV == End of Buffer (window displays current buffer)
+
+BEG_BYTE == Beginning Byte of Buffer
+
+Z_BYTE == Ending Byte of Buffer
+
+NARROWED -- "V":
+
+BEGV == Beginning of NARROWED Buffer (window displays current buffer)
+
+ZV == End of NARROWED Buffer (window displays current buffer)
+
+BEGV_BYTE == Beginning Byte of NARROWED Buffer
+
+ZV_BYTE == Ending Byte of NARROWED buffer
+
+WINDOW DOES NOT NECESSARILY DISPLAY BUFFER:
+
+bob_disregard_narrow = BUF_BEG (buffer)
+eob_disregard_narrow = BUF_Z (buffer)
+
+bob_respect_narrow = BUF_BEGV (buffer)
+eob_respect_narrow = BUF_ZV (buffer)
+
+window_start = marker_position (w->start)
+window_end = eob_disregard_narrow - w->window_end_pos
+
+buffer_size = eob_disregard_narrow - bob_disregard_narrow
+
+buffer_narrowed_p = (eob_respect_narrow - bob_respect_narrow != buffer_size)
+
+window_contents_visible_p = (bob_respect_narrow == window_start
+                             && eob_respect_narrow == window_end)
+
+This is the C [ternary operator][1] (Objective-C is a superset of C):
+
+    label.frame = (inPseudoEditMode) ? kLabelIndentedRect : kLabelRect;
+
+is semantically equivalent to
+
+    if(inPseudoEditMode) {
+     label.frame = kLabelIndentedRect;
+    } else {
+     label.frame = kLabelRect;
+    }
+
+The ternary with no first element (e.g. `variable ?: anotherVariable`) means the same as `(valOrVar != 0) ? valOrVar : anotherValOrVar`
+
+EASSERT:
+
+  eassert (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b));
+  bool barf_crash = (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b)) ? false : true; */
+
+#include <time.h>
+#include <ftoastr.h>
+
+#define NO_FRINGE_BITMAP 0
+
+#define LEFT_FRINGE_BITMAP -3
+
+#define RIGHT_FRINGE_BITMAP -4
+
+/* Text cursor types.  */
+
+enum type_of_action
+{
+  MULTIPLE_CURSORS,
+  HORIZONTAL_RULER,
+  VERTICAL_RULER,
+  FILL_COLUMN
+};
+
+/* Function prototypes.  */
+
+static void debug_method_add (struct window *, char const *, ...);
+
+static int window_hscroll_limited (struct window *, struct frame *);
+
+/* Record FROM_WHERE when `redisplay_preserve_echo_area' is called. */
+static int mc_redisplay_preserve_echo_area;
+
+/* Record FROM_WHERE when `redisplay' is called. */
+static int mc_redisplay;
+
+/* Record FROM_WHERE when `redisplay_internal' is called. */
+static int mc_redisplay_internal;
+
+/* Used for debugging. */
+static bool mc_debug_p;
+
+/* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
+   DP is a display table or NULL. */
+
+#define MC_MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width)			\
+  do {									\
+    int ch;								\
+										\
+    ch = STRING_CHAR_AND_LENGTH (p, bytes);				\
+    if (BYTES_BY_CHAR_HEAD (*p) != bytes)				\
+      width = bytes * 4;						\
+    else								\
+      {									\
+	if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch)))		\
+	  width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \
+	else								\
+	  width = CHARACTER_WIDTH (ch);					\
+      }									\
+  } while (0)
+
+/* Check the presence of a display property and compute its width.
+   If a property was found and its width was found as well, return
+   its width (>= 0) and set the position of the end of the property
+   in ENDPOS.
+   Otherwise just return -1.  */
+static int
+mc_check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos)
+{
+  Lisp_Object val, overlay;
+  if (CONSP (val = get_char_property_and_overlay
+       (make_fixnum (pos), Qdisplay, Qnil, &overlay))
+      && EQ (Qspace, XCAR (val)))
+    { /* FIXME: Use calc_pixel_width_or_height.  */
+      Lisp_Object plist = XCDR (val), prop;
+      int width = -1;
+      EMACS_INT align_to_max =
+  (col < MOST_POSITIVE_FIXNUM - INT_MAX
+   ? (EMACS_INT) INT_MAX + col
+   : MOST_POSITIVE_FIXNUM);
+      if ((prop = Fplist_get (plist, QCwidth),
+     RANGED_FIXNUMP (0, prop, INT_MAX))
+    || (prop = Fplist_get (plist, QCrelative_width),
+        RANGED_FIXNUMP (0, prop, INT_MAX)))
+  width = XFIXNUM (prop);
+      else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop)
+         && XFLOAT_DATA (prop) <= INT_MAX)
+  width = (int)(XFLOAT_DATA (prop) + 0.5);
+      else if ((prop = Fplist_get (plist, QCalign_to),
+    RANGED_FIXNUMP (col, prop, align_to_max)))
+  width = XFIXNUM (prop) - col;
+      else if (FLOATP (prop) && col <= XFLOAT_DATA (prop)
+         && (XFLOAT_DATA (prop) <= align_to_max))
+  width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
+      if (width >= 0)
+  {
+    ptrdiff_t start;
+    if (OVERLAYP (overlay))
+      *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+    else
+      get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
+    /* For :relative-width, we need to multiply by the column
+       width of the character at POS, if it is greater than 1.  */
+    if (!NILP (Fplist_get (plist, QCrelative_width))
+        && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
+      {
+        int b, wd;
+        unsigned char *p = BYTE_POS_ADDR (CHAR_TO_BYTE (pos));
+        MC_MULTIBYTE_BYTES_WIDTH (p, buffer_display_table (), b, wd);
+        width *= wd;
+      }
+    return width;
+  }
+    }
+  return -1;
+}
+
+/* Scanning from the beginning of the current line, stop at the buffer
+   position ENDPOS or at the column GOALCOL or at the end of line, whichever
+   comes first.
+   Return the resulting buffer position and column in ENDPOS and GOALCOL.
+   PREVCOL gets set to the column of the previous position (it's always
+   strictly smaller than the goal column).  */
+void
+mc_scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol, ptrdiff_t pt)
+{
+  EMACS_INT last_known_column_modified = 0;
+  ptrdiff_t last_known_column = 0;
+  int tab_width = SANE_TAB_WIDTH (current_buffer);
+  bool ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
+  struct Lisp_Char_Table *dp = buffer_display_table ();
+  bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
+  struct composition_it cmp_it;
+  Lisp_Object window;
+  struct window *w;
+  /* Start the scan at the beginning of this line with column number 0.  */
+  register ptrdiff_t col = 0, prev_col = 0;
+  EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
+  ptrdiff_t end = endpos ? *endpos : pt;
+  ptrdiff_t scan, scan_byte, next_boundary;
+  scan = find_newline (pt, CHAR_TO_BYTE (pt), BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1);
+  next_boundary = scan;
+  window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
+  w = ! NILP (window) ? XWINDOW (window) : NULL;
+  memset (&cmp_it, 0, sizeof cmp_it);
+  cmp_it.id = -1;
+  composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
+  /* Scan forward to the target position.  */
+  while (scan < end)
+    {
+      int c;
+      /* Occasionally we may need to skip invisible text.  */
+      while (scan == next_boundary)
+  {
+    ptrdiff_t old_scan = scan;
+    /* This updates NEXT_BOUNDARY to the next place
+       where we might need to skip more invisible text.  */
+    scan = skip_invisible (scan, &next_boundary, end, Qnil);
+    if (scan != old_scan)
+      scan_byte = CHAR_TO_BYTE (scan);
+    if (scan >= end)
+      goto endloop;
+  }
+      /* Test reaching the goal column.  We do this after skipping
+   invisible characters, so that we put point before the
+   character on which the cursor will appear.  */
+      if (col >= goal)
+  break;
+      prev_col = col;
+      { /* Check display property.  */
+  ptrdiff_t endp;
+  int width = mc_check_display_width (scan, col, &endp);
+  if (width >= 0)
+    {
+      col += width;
+      if (endp > scan) /* Avoid infinite loops with 0-width overlays.  */
+        {
+    scan = endp;
+    scan_byte = CHAR_TO_BYTE (scan);
+    continue;
+        }
+    }
+      }
+      /* Check composition sequence.  */
+      if (cmp_it.id >= 0
+    || (scan == cmp_it.stop_pos
+        && composition_reseat_it (&cmp_it, scan, scan_byte, end,
+          w, NULL, Qnil)))
+  composition_update_it (&cmp_it, scan, scan_byte, Qnil);
+      if (cmp_it.id >= 0)
+  {
+    scan += cmp_it.nchars;
+    scan_byte += cmp_it.nbytes;
+    if (scan <= end)
+      col += cmp_it.width;
+    if (cmp_it.to == cmp_it.nglyphs)
+      {
+        cmp_it.id = -1;
+        composition_compute_stop_pos (&cmp_it, scan, scan_byte, end,
+              Qnil);
+      }
+    else
+      cmp_it.from = cmp_it.to;
+    continue;
+  }
+      c = FETCH_BYTE (scan_byte);
+      /* See if there is a display table and it relates
+   to this character.  */
+      if (dp != 0
+    && ! (multibyte && LEADING_CODE_P (c))
+    && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+  {
+    Lisp_Object charvec;
+    ptrdiff_t i, n;
+    /* This character is displayed using a vector of glyphs.
+       Update the column/position based on those glyphs.  */
+    charvec = DISP_CHAR_VECTOR (dp, c);
+    n = ASIZE (charvec);
+    for (i = 0; i < n; i++)
+      {
+        /* This should be handled the same as
+     next_element_from_display_vector does it.  */
+        Lisp_Object entry = AREF (charvec, i);
+        if (GLYPH_CODE_P (entry))
+    c = GLYPH_CODE_CHAR (entry);
+        else
+    c = ' ';
+        if (c == '\n')
+    goto endloop;
+        if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
+    goto endloop;
+        if (c == '\t')
+    {
+      col += tab_width;
+      col = col / tab_width * tab_width;
+    }
+        else
+    ++col;
+      }
+  }
+      else
+  {
+    /* The display table doesn't affect this character;
+       it displays as itself.  */
+    if (c == '\n')
+      goto endloop;
+    if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
+      goto endloop;
+    if (c == '\t')
+      {
+        col += tab_width;
+        col = col / tab_width * tab_width;
+      }
+    else if (multibyte && LEADING_CODE_P (c))
+      {
+        /* Start of multi-byte form.  */
+        unsigned char *ptr;
+        int bytes, width;
+        ptr = BYTE_POS_ADDR (scan_byte);
+        MC_MULTIBYTE_BYTES_WIDTH (ptr, dp, bytes, width);
+        /* Subtract one to compensate for the increment
+     that is going to happen below.  */
+        scan_byte += bytes - 1;
+        col += width;
+      }
+    else if (ctl_arrow && (c < 040 || c == 0177))
+      col += 2;
+    else if (c < 040 || c >= 0177)
+      col += 4;
+    else
+      col++;
+  }
+      scan++;
+      scan_byte++;
+    }
+ endloop:
+  last_known_column = col;
+  last_known_column_point = pt;
+  last_known_column_modified = MODIFF;
+  if (goalcol)
+    *goalcol = col;
+  if (endpos)
+    *endpos = scan;
+  if (prevcol)
+    *prevcol = prev_col;
+}
+
+ptrdiff_t
+mc_current_column (struct window *w, ptrdiff_t pt)
+{
+  /* `buf_charpos_to_bytepos':  eassert (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b)); */
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  bool barf_crash = (BUF_BEG (b) <= pt && pt <= BUF_Z (b)) ? false : true;
+  if (barf_crash)
+    return 0;
+  EMACS_INT last_known_column_modified = 0;
+  ptrdiff_t last_known_column = 0;
+  ptrdiff_t col;
+  unsigned char *ptr, *stop;
+  bool tab_seen;
+  ptrdiff_t post_tab;
+  int c;
+  int tab_width = SANE_TAB_WIDTH (current_buffer);
+  bool ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
+  struct Lisp_Char_Table *dp = buffer_display_table ();
+  if (pt == last_known_column_point
+      && MODIFF == last_known_column_modified)
+    return last_known_column;
+  /* If the buffer has overlays, text properties,
+     or multibyte characters, use a more general algorithm.  */
+  if (buffer_intervals (current_buffer)
+      || buffer_has_overlays ()
+      || Z != Z_BYTE)
+    {
+      EMACS_INT col = MOST_POSITIVE_FIXNUM;
+      mc_scan_for_column (&pt, &col, NULL, pt);
+      return col;
+    }
+  /* Scan backwards from point to the previous newline,
+     counting width.  Tab characters are the only complicated case.  */
+  /* Make a pointer for decrementing through the chars before point.  */
+  ptr = BYTE_POS_ADDR (CHAR_TO_BYTE (pt) - 1) + 1;
+  /* Make a pointer to where consecutive chars leave off,
+     going backwards from point.  */
+  if (pt == BEGV)
+    stop = ptr;
+  else if (pt <= GPT || BEGV > GPT)
+    stop = BEGV_ADDR;
+  else
+    stop = GAP_END_ADDR;
+  col = 0, tab_seen = 0, post_tab = 0;
+  while (1)
+    {
+      ptrdiff_t i, n;
+      Lisp_Object charvec;
+      if (ptr == stop)
+  {
+    /* We stopped either for the beginning of the buffer
+       or for the gap.  */
+    if (ptr == BEGV_ADDR)
+      break;
+    /* It was the gap.  Jump back over it.  */
+    stop = BEGV_ADDR;
+    ptr = GPT_ADDR;
+    /* Check whether that brings us to beginning of buffer.  */
+    if (BEGV >= GPT)
+      break;
+  }
+      c = *--ptr;
+      if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+  {
+    charvec = DISP_CHAR_VECTOR (dp, c);
+    n = ASIZE (charvec);
+  }
+      else
+  {
+    charvec = Qnil;
+    n = 1;
+  }
+      for (i = n - 1; i >= 0; --i)
+  {
+    if (VECTORP (charvec))
+      {
+        /* This should be handled the same as
+     next_element_from_display_vector does it.  */
+        Lisp_Object entry = AREF (charvec, i);
+        if (GLYPH_CODE_P (entry))
+    c = GLYPH_CODE_CHAR (entry);
+        else
+    c = ' ';
+      }
+    if (c >= 040 && c < 0177)
+      col++;
+    else if (c == '\n'
+       || (c == '\r'
+           && EQ (BVAR (current_buffer, selective_display), Qt)))
+      {
+        ptr++;
+        goto start_of_line_found;
+      }
+    else if (c == '\t')
+      {
+        if (tab_seen)
+    col = ((col + tab_width) / tab_width) * tab_width;
+        post_tab += col;
+        col = 0;
+        tab_seen = 1;
+      }
+    else if (VECTORP (charvec))
+      /* With a display table entry, C is displayed as is, and
+         not displayed as \NNN or as ^N.  If C is a single-byte
+         character, it takes one column.  If C is multi-byte in
+         a unibyte buffer, it's translated to unibyte, so it
+         also takes one column.  */
+      ++col;
+    else
+      col += (ctl_arrow && c < 0200) ? 2 : 4;
+  }
+    }
+ start_of_line_found:
+  if (tab_seen)
+    {
+      col = ((col + tab_width) / tab_width) * tab_width;
+      col += post_tab;
+    }
+  last_known_column = col;
+  last_known_column_point = pt;
+  last_known_column_modified = MODIFF;
+  return col;
+}
+
+static 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, "left-fringe-bitmap"))
+    return LEFT_FRINGE_BITMAP;
+  if (!strcmp (str, "right-fringe-bitmap"))
+    return RIGHT_FRINGE_BITMAP;
+  if (!strcmp (str, "no"))
+    return NO_CURSOR;
+  return -1;
+}
+
+static Lisp_Object
+mc_cursor_type_to_lisp (int arg)
+{
+  switch (arg)
+    {
+    case FILLED_BOX_CURSOR: return Qbox;
+    case HOLLOW_BOX_CURSOR: return Qhollow;
+    case HBAR_CURSOR: return Qhbar;
+    case BAR_CURSOR: return Qbar;
+    case LEFT_FRINGE_BITMAP: return intern ("left-fringe-bitmap");
+    case RIGHT_FRINGE_BITMAP: return intern ("right-fringe-bitmap");
+    case NO_CURSOR:
+    default: return intern ("no");
+    }
+}
+
+static Lisp_Object
+mc_color_vector_calc (struct window *w, Lisp_Object color)
+{
+  CHECK_STRING (color);
+  Lisp_Object target_frame = w->frame;
+  Lisp_Object color_values;
+  double valmax = XFIXNUM (XCAR (Fxw_color_values (build_string ("#ffffff"), target_frame)));
+  Lisp_Object vlist;
+  ptrdiff_t x;
+  int i = 0;
+  Lisp_Object temp = Qnil;
+  Lisp_Object vector = (Fmake_vector (make_fixnum (3), Qnil));
+  if (!NILP (Fmemq ((Fframep (target_frame)), listn (CONSTYPE_HEAP, 3, intern ("x"), intern ("w32"), intern ("ns")))))
+    {
+      color_values = (Fxw_color_values (color, target_frame));
+      for (vlist = color_values;
+           CONSP (vlist);
+           vlist = XCDR (vlist))
+        {
+          x = XFIXNUM (XCAR (vlist));
+          temp = make_float (x / valmax);
+          ASET (vector, i, temp);
+          i = i + 1;
+        }
+    }
+  return vector;
+}
+
+static Lisp_Object
+mc_bg_lsl (struct window *w, enum face_id face_id)
+{
+  struct frame *f = XFRAME (w->frame);
+  struct face *face;
+  Lisp_Object color, color_vector;
+  if (!NILP (Vface_remapping_alist)
+      && (face_id == DEFAULT_FACE_ID /* Qdefault */
+          || face_id == MODE_LINE_FACE_ID /* Qmode_line */
+          || face_id == MODE_LINE_INACTIVE_FACE_ID /* Qmode_line_inactive */
+          || face_id == HEADER_LINE_FACE_ID /* Qheader_line */
+          || face_id == TOOL_BAR_FACE_ID /* Qtool_bar */
+          || face_id == FRINGE_FACE_ID /* Qfringe */
+          || face_id == SCROLL_BAR_FACE_ID /* Qscroll_bar */
+          || face_id == BORDER_FACE_ID /* Qborder */
+          || face_id == CURSOR_FACE_ID /* Qcursor */
+          || face_id == MOUSE_FACE_ID /* Qmouse */
+          || face_id == MENU_FACE_ID /* Qmenu */
+          || face_id == WINDOW_DIVIDER_FACE_ID /* Qwindow_divider */
+          || face_id == WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID /* Qwindow_divider_first_pixel */
+          || face_id == WINDOW_DIVIDER_LAST_PIXEL_FACE_ID /* Qwindow_divider_last_pixel */
+          || face_id == VERTICAL_BORDER_FACE_ID /* Qvertical_border */
+          || face_id == INTERNAL_BORDER_FACE_ID)) /* Qinternal_border */
+    face = FACE_FROM_ID (f, lookup_basic_face (w, f, face_id));
+    else
+      face = FACE_FROM_ID (f, face_id);
+  color = face->lface[LFACE_BACKGROUND_INDEX];
+  CHECK_STRING (color);
+  color_vector = mc_color_vector_calc (w, color);
+  return color_vector;
+}
+
+static Lisp_Object
+mc_fg_lsl (struct window *w, enum face_id face_id)
+{
+  struct frame *f = XFRAME (w->frame);
+  struct face *face;
+  Lisp_Object color, color_vector;
+  if (!NILP (Vface_remapping_alist)
+      && (face_id == DEFAULT_FACE_ID /* Qdefault */
+          || face_id == MODE_LINE_FACE_ID /* Qmode_line */
+          || face_id == MODE_LINE_INACTIVE_FACE_ID /* Qmode_line_inactive */
+          || face_id == HEADER_LINE_FACE_ID /* Qheader_line */
+          || face_id == TOOL_BAR_FACE_ID /* Qtool_bar */
+          || face_id == FRINGE_FACE_ID /* Qfringe */
+          || face_id == SCROLL_BAR_FACE_ID /* Qscroll_bar */
+          || face_id == BORDER_FACE_ID /* Qborder */
+          || face_id == CURSOR_FACE_ID /* Qcursor */
+          || face_id == MOUSE_FACE_ID /* Qmouse */
+          || face_id == MENU_FACE_ID /* Qmenu */
+          || face_id == WINDOW_DIVIDER_FACE_ID /* Qwindow_divider */
+          || face_id == WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID /* Qwindow_divider_first_pixel */
+          || face_id == WINDOW_DIVIDER_LAST_PIXEL_FACE_ID /* Qwindow_divider_last_pixel */
+          || face_id == VERTICAL_BORDER_FACE_ID /* Qvertical_border */
+          || face_id == INTERNAL_BORDER_FACE_ID)) /* Qinternal_border */
+    face = FACE_FROM_ID (f, lookup_basic_face (w, f, face_id));
+    else
+      face = FACE_FROM_ID (f, face_id);
+  color = face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (color);
+  color_vector = mc_color_vector_calc (w, color);
+  return color_vector;
+}
+
+static Lisp_Object
+mc_fg_face (struct window *w, enum face_id face_id)
+{
+  struct frame *f = XFRAME (w->frame);
+  struct face *face;
+  if (!NILP (Vface_remapping_alist)
+      && (face_id == DEFAULT_FACE_ID /* Qdefault */
+          || face_id == MODE_LINE_FACE_ID /* Qmode_line */
+          || face_id == MODE_LINE_INACTIVE_FACE_ID /* Qmode_line_inactive */
+          || face_id == HEADER_LINE_FACE_ID /* Qheader_line */
+          || face_id == TOOL_BAR_FACE_ID /* Qtool_bar */
+          || face_id == FRINGE_FACE_ID /* Qfringe */
+          || face_id == SCROLL_BAR_FACE_ID /* Qscroll_bar */
+          || face_id == BORDER_FACE_ID /* Qborder */
+          || face_id == CURSOR_FACE_ID /* Qcursor */
+          || face_id == MOUSE_FACE_ID /* Qmouse */
+          || face_id == MENU_FACE_ID /* Qmenu */
+          || face_id == WINDOW_DIVIDER_FACE_ID /* Qwindow_divider */
+          || face_id == WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID /* Qwindow_divider_first_pixel */
+          || face_id == WINDOW_DIVIDER_LAST_PIXEL_FACE_ID /* Qwindow_divider_last_pixel */
+          || face_id == VERTICAL_BORDER_FACE_ID /* Qvertical_border */
+          || face_id == INTERNAL_BORDER_FACE_ID)) /* Qinternal_border */
+    face = FACE_FROM_ID (f, lookup_basic_face (w, f, face_id));
+    else
+      face = FACE_FROM_ID (f, face_id);
+  return face->lface[LFACE_FOREGROUND_INDEX];
+}
+
+static Lisp_Object
+mc_bg_face (struct window *w, enum face_id face_id)
+{
+  struct frame *f = XFRAME (w->frame);
+  struct face *face;
+  if (!NILP (Vface_remapping_alist)
+      && (face_id == DEFAULT_FACE_ID /* Qdefault */
+          || face_id == MODE_LINE_FACE_ID /* Qmode_line */
+          || face_id == MODE_LINE_INACTIVE_FACE_ID /* Qmode_line_inactive */
+          || face_id == HEADER_LINE_FACE_ID /* Qheader_line */
+          || face_id == TOOL_BAR_FACE_ID /* Qtool_bar */
+          || face_id == FRINGE_FACE_ID /* Qfringe */
+          || face_id == SCROLL_BAR_FACE_ID /* Qscroll_bar */
+          || face_id == BORDER_FACE_ID /* Qborder */
+          || face_id == CURSOR_FACE_ID /* Qcursor */
+          || face_id == MOUSE_FACE_ID /* Qmouse */
+          || face_id == MENU_FACE_ID /* Qmenu */
+          || face_id == WINDOW_DIVIDER_FACE_ID /* Qwindow_divider */
+          || face_id == WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID /* Qwindow_divider_first_pixel */
+          || face_id == WINDOW_DIVIDER_LAST_PIXEL_FACE_ID /* Qwindow_divider_last_pixel */
+          || face_id == VERTICAL_BORDER_FACE_ID /* Qvertical_border */
+          || face_id == INTERNAL_BORDER_FACE_ID)) /* Qinternal_border */
+    face = FACE_FROM_ID (f, lookup_basic_face (w, f, face_id));
+    else
+      face = FACE_FROM_ID (f, face_id);
+  return face->lface[LFACE_BACKGROUND_INDEX];
+}
+
+struct face *
+mc_lookup_face (struct it *it)
+{
+  if (!NILP (Vface_remapping_alist)
+      && (it->face_id == DEFAULT_FACE_ID /* Qdefault */
+          || it->face_id == MODE_LINE_FACE_ID /* Qmode_line */
+          || it->face_id == MODE_LINE_INACTIVE_FACE_ID /* Qmode_line_inactive */
+          || it->face_id == HEADER_LINE_FACE_ID /* Qheader_line */
+          || it->face_id == TOOL_BAR_FACE_ID /* Qtool_bar */
+          || it->face_id == FRINGE_FACE_ID /* Qfringe */
+          || it->face_id == SCROLL_BAR_FACE_ID /* Qscroll_bar */
+          || it->face_id == BORDER_FACE_ID /* Qborder */
+          || it->face_id == CURSOR_FACE_ID /* Qcursor */
+          || it->face_id == MOUSE_FACE_ID /* Qmouse */
+          || it->face_id == MENU_FACE_ID /* Qmenu */
+          || it->face_id == WINDOW_DIVIDER_FACE_ID /* Qwindow_divider */
+          || it->face_id == WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID /* Qwindow_divider_first_pixel */
+          || it->face_id == WINDOW_DIVIDER_LAST_PIXEL_FACE_ID /* Qwindow_divider_last_pixel */
+          || it->face_id == VERTICAL_BORDER_FACE_ID /* Qvertical_border */
+          || it->face_id == INTERNAL_BORDER_FACE_ID)) /* Qinternal_border */
+    return FACE_FROM_ID (it->f, lookup_basic_face (it->w, it->f, it->face_id));
+      else
+        return FACE_FROM_ID (it->f, it->face_id);
+}
+
+/* nth 0 => false, false
+   nth 1 => true, false
+   nth 2 => false, true
+   nth 3 => true, true
+  Lookup in buffer-local fringe-indicator-alist before global alist.
+     Elements are:
+  BITMAP    -- use for all
+  (L R)    -- use for left right (whether partial or not)
+  (L R PL PR)  -- use for left right partial-left partial-right
+  If any value in local binding is not present or t, use global value.
+     If partial, lookup partial bitmap in default value if not found here.
+     If not partial, or no partial spec is present, use non-partial bitmap.  */
+
+static int
+mc_get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p)
+{
+  Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
+  EMACS_INT ln1 = 0, ln2 = 0;
+  int ix1 = right_p;
+  int ix2 = ix1 + (partial_p ? 2 : 0);
+  if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
+    {
+      bm1 = Fassq (bitmap, cmap);
+      if (CONSP (bm1))
+  {
+    if ((bm1 = XCDR (bm1)), NILP (bm1))
+      return NO_FRINGE_BITMAP;
+    if (CONSP (bm1))
+      {
+        ln1 = XFIXNUM (Flength (bm1));
+        if (partial_p)
+    {
+      if (ln1 > ix2)
+        {
+          bm = Fnth (make_fixnum (ix2), bm1);
+          if (!EQ (bm, Qt))
+      goto found;
+        }
+    }
+        else
+    {
+      if (ln1 > ix1)
+        {
+          bm = Fnth (make_fixnum (ix1), bm1);
+          if (!EQ (bm, Qt))
+      goto found;
+        }
+    }
+      }
+    else if ((bm = bm1, !EQ (bm, Qt)))
+      goto found;
+  }
+    }
+  if (!EQ (cmap, BVAR (&buffer_defaults, fringe_indicator_alist))
+      && !NILP (BVAR (&buffer_defaults, fringe_indicator_alist)))
+    {
+      bm2 = Fassq (bitmap, BVAR (&buffer_defaults, fringe_indicator_alist));
+      if (CONSP (bm2))
+  {
+    if ((bm2 = XCDR (bm2)), !NILP (bm2))
+      {
+        if (CONSP (bm2))
+    {
+      ln2 = XFIXNUM (Flength (bm2));
+      if (partial_p)
+        {
+          if (ln2 > ix2)
+      {
+        bm = Fnth (make_fixnum (ix2), bm2);
+        if (!EQ (bm, Qt))
+          goto found;
+      }
+        }
+    }
+      }
+  }
+    }
+  if (ln1 > ix1)
+    {
+      bm = Fnth (make_fixnum (ix1), bm1);
+      if (!EQ (bm, Qt))
+  goto found;
+    }
+  if (ln2 > ix1)
+    {
+      bm = Fnth (make_fixnum (ix1), bm2);
+      if (!EQ (bm, Qt))
+  goto found;
+      return NO_FRINGE_BITMAP;
+    }
+  else if ((bm = bm2, NILP (bm)))
+    return NO_FRINGE_BITMAP;
+ found:
+  return lookup_fringe_bitmap (bm);
+}
+
+void
+mc_erase_phys_cursor (struct window *w, int flavor)
+{
+  struct frame *f = XFRAME (w->frame);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+  int hpos = w->phys_cursor.hpos;
+  int vpos = w->phys_cursor.vpos;
+  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;
+  /* No cursor displayed or row invalidated => nothing to do on the
+     screen.  */
+  if (w->phys_cursor_type == NO_CURSOR)
+    goto mark_cursor_off;
+  /* VPOS >= active_glyphs->nrows means that window has been resized.
+     Don't bother to erase the cursor.  */
+  if (vpos >= active_glyphs->nrows)
+    goto mark_cursor_off;
+  /* If row containing cursor is marked invalid, there is nothing we
+     can do.  */
+  cursor_row = MATRIX_ROW (active_glyphs, vpos);
+  if (!cursor_row->enabled_p)
+    goto mark_cursor_off;
+  /* If line spacing is > 0, old cursor may only be partially visible in
+     window after split-window.  So adjust visible height.  */
+  cursor_row->visible_height = min (cursor_row->visible_height,
+            window_text_bottom_y (w) - cursor_row->y);
+  /* If row is completely invisible, don't attempt to delete a cursor which
+     isn't there.  This can happen if cursor is at top of a window, and
+     we switch to a buffer with a header line in that window.  */
+  if (cursor_row->visible_height <= 0)
+    goto mark_cursor_off;
+  /* If cursor is in the fringe, erase by drawing actual bitmap there.  */
+  if (cursor_row->cursor_in_fringe_p
+      && flavor != MC_GLYPH)
+    {
+      cursor_row->cursor_in_fringe_p = false;
+      draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
+      goto mark_cursor_off;
+    }
+  /* This can happen when the new row is shorter than the old one.
+     In this case, either draw_glyphs or clear_end_of_line
+     should have cleared the cursor.  Note that we wouldn't be
+     able to erase the cursor in this case because we don't have a
+     cursor glyph at hand.  */
+  if ((cursor_row->reversed_p
+       ? (w->phys_cursor.hpos < 0)
+       : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
+    goto mark_cursor_off;
+  /* 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 the cursor is in the mouse face area, redisplay that when
+     we clear the cursor.  */
+  if (! NILP (hlinfo->mouse_face_window)
+      && coords_in_mouse_face_p (w, hpos, vpos)
+      /* Don't redraw the cursor's spot in mouse face if it is at the
+   end of a line (on a newline).  The cursor appears there, but
+   mouse highlighting does not.  */
+      && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
+    mouse_face_here_p = true;
+  /* Maybe clear the display under the cursor.  */
+  if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
+    {
+      int x, y;
+      int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+      int width;
+      cursor_glyph = get_phys_cursor_glyph (w);
+      if (cursor_glyph == NULL)
+        goto mark_cursor_off;
+      width = cursor_glyph->pixel_width;
+      x = w->phys_cursor.x;
+      if (x < 0)
+        {
+          width += x;
+          x = 0;
+        }
+      width = min (width, window_box_width (w, TEXT_AREA) - x);
+      y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
+      x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+      if (width > 0)
+  FRAME_RIF (f)->clear_frame_area (f, x, 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;
+  draw_phys_cursor_glyph (w, cursor_row, hl);
+ mark_cursor_off:
+  w->phys_cursor_on_p = false;
+  w->phys_cursor_type = NO_CURSOR;
+}
+
+static void
+mc_erase_glyph_cursors (struct window *w, int x, int y, int hpos, int vpos,
+                        enum text_cursor_kinds cursor_type, int cursor_width,
+                        int flavor)
+{
+  /* `matrix_row' in `dispnew.c` contains the following tests,
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows); */
+  bool barf_crash_one = (w->current_matrix && w->current_matrix->rows) ? false : true;
+  if (barf_crash_one)
+    return;
+  bool barf_crash_two = (vpos >= 0 && vpos < w->current_matrix->nrows) ? false : true;
+  if (barf_crash_two)
+    return;
+  if (x < 0
+      || y < 0
+      || hpos < 0
+      || vpos < 0)
+    return;
+  /* Record some of the current values for the cursor and glyph_row. */
+  bool phys_cursor_on_p = w->phys_cursor_on_p;
+  struct glyph_row *glyph_row = MATRIX_ROW (w->current_matrix, vpos);
+  bool cursor_in_fringe_p = glyph_row->cursor_in_fringe_p;
+  bool reversed_p = glyph_row->reversed_p;
+  ptrdiff_t phys_cursor_x = w->phys_cursor.x;
+  ptrdiff_t phys_cursor_y = w->phys_cursor.y;
+  ptrdiff_t phys_cursor_hpos = w->phys_cursor.hpos;
+  ptrdiff_t phys_cursor_vpos = w->phys_cursor.vpos;
+  ptrdiff_t phys_cursor_ascent = w->phys_cursor_ascent;
+  ptrdiff_t phys_cursor_height = w->phys_cursor_height;
+  ptrdiff_t phys_cursor_width = w->phys_cursor_width;
+  enum text_cursor_kinds phys_cursor_type = w->phys_cursor_type;
+  /* Hijack w->phys_cursor. */
+  w->phys_cursor.x = x;
+  w->phys_cursor.y = y;
+  w->phys_cursor.hpos = hpos;
+  w->phys_cursor.vpos = vpos;
+  w->phys_cursor_type = cursor_type;
+  w->phys_cursor_ascent = glyph_row->ascent;
+  w->phys_cursor_height = glyph_row->height;
+  w->phys_cursor_width = cursor_width;
+  mc_erase_phys_cursor (w, flavor);
+  /* Restore the previous values for w->phys_cursor and glyph_row. */
+  w->phys_cursor_on_p = phys_cursor_on_p;
+  w->phys_cursor.x = phys_cursor_x;
+  w->phys_cursor.y = phys_cursor_y;
+  w->phys_cursor.hpos = phys_cursor_hpos;
+  w->phys_cursor.vpos = phys_cursor_vpos;
+  w->phys_cursor_type = phys_cursor_type;
+  glyph_row->cursor_in_fringe_p = cursor_in_fringe_p;
+  glyph_row->reversed_p = reversed_p;
+  w->phys_cursor_ascent = phys_cursor_ascent;
+  w->phys_cursor_height = phys_cursor_height;
+  w->phys_cursor_width = phys_cursor_width;
+}
+
+/* We call this a draw/erase hybrid because it does all of the following:
+-  Draw all glyph cursors, but erase with `mc_erase_glyph_cursors'.
+-  Draw/erase all fringe bitmaps relating to crosshairs.
+-  Draw/erase all glyphless cursors. */
+
+static void
+mc_draw_erase_hybrid (struct window *w, int x, int fx, int y, int fy, int hpos, int vpos,
+                      int h, enum text_cursor_kinds cursor_type, int cursor_width,
+                      Lisp_Object color_vector, bool active_p, bool minimal_p,
+                      int flavor, int posint, bool remove_p)
+{
+  /* `matrix_row' in `dispnew.c` contains the following tests,
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows); */
+  bool barf_crash_one = (w->current_matrix && w->current_matrix->rows) ? false : true;
+  if (barf_crash_one)
+    return;
+  bool barf_crash_two = (vpos >= 0 && vpos < w->current_matrix->nrows) ? false : true;
+  if (barf_crash_two)
+    return;
+  if (x < 0
+      || y < 0
+      || hpos < 0
+      || vpos < 0)
+    return;
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  bool auto_hscroll_mode_p = EQ (Fbuffer_local_value (Qauto_hscroll_mode, buf), Qcurrent_line);
+  /* EXAMPLE:  (scroll-left 5) */
+  bool hscl_all_temp_p = (w->suspend_auto_hscroll
+                          && auto_hscroll_mode_p
+                          && w->hscroll > 0
+                          && w->min_hscroll == 0);
+  /* EXAMPLE:  C-u C-x < and do nothing. */
+  bool hscl_all_perm_0_p = (w->suspend_auto_hscroll
+                            && auto_hscroll_mode_p
+                            && w->hscroll > 0
+                            && w->min_hscroll > 0
+                            && w->min_hscroll == w->hscroll);
+  /* EXAMPLE:  C-u C-x < and do something else besides horizontally scrolling the
+               current line differently.
+               Current line is _not_ horizontally scrolled differently. */
+  bool hscl_all_perm_1_p = (!w->suspend_auto_hscroll
+                            && auto_hscroll_mode_p
+                            && w->hscroll > 0
+                            && w->min_hscroll > 0
+                            && w->min_hscroll == w->hscroll);
+  /* EXAMPLE:  C-u C-x < and ...
+               Current line is _not_ horizontally scrolled differently. */
+  bool hscl_all_perm_2_p = (!w->suspend_auto_hscroll
+                            && auto_hscroll_mode_p
+                            && w->hscroll == 0
+                            && w->min_hscroll > 0
+                            && w->min_hscroll != w->hscroll);
+  /* EXAMPLE:  (scroll-left 5); and, then press the left arrow key one time.
+               Current line _is_ horizontally scrolled differently.*/
+  bool hscl_temp_p = (!w->suspend_auto_hscroll
+                      && auto_hscroll_mode_p
+                      && w->hscroll > 0
+                      && w->min_hscroll == 0);
+  /* EXAMPLE:  C-u C-x < and do something that causes the current line to be
+               horizontally scrolled differently.
+               Current line _is_ horizontally scrolled differently. */
+  bool hscl_perm_p = (!w->suspend_auto_hscroll
+                      && auto_hscroll_mode_p
+                      && w->hscroll > 0
+                      && w->min_hscroll > 0
+                      && w->min_hscroll != w->hscroll);
+  struct frame *f = XFRAME (w->frame);
+  /* Record some of the current values for the cursor and glyph_row. */
+  bool phys_cursor_on_p = w->phys_cursor_on_p;
+  struct glyph_row *glyph_row = MATRIX_ROW (w->current_matrix, vpos);
+  bool cursor_in_fringe_p = glyph_row->cursor_in_fringe_p;
+  bool reversed_p = glyph_row->reversed_p;
+  ptrdiff_t phys_cursor_x = w->phys_cursor.x;
+  ptrdiff_t phys_cursor_y = w->phys_cursor.y;
+  ptrdiff_t phys_cursor_hpos = w->phys_cursor.hpos;
+  ptrdiff_t phys_cursor_vpos = w->phys_cursor.vpos;
+  ptrdiff_t phys_cursor_ascent = w->phys_cursor_ascent;
+  ptrdiff_t phys_cursor_height = w->phys_cursor_height;
+  ptrdiff_t phys_cursor_width = w->phys_cursor_width;
+  enum text_cursor_kinds phys_cursor_type = w->phys_cursor_type;
+  /* Hijack w->phys_cursor. */
+  w->phys_cursor.x = x;
+  w->phys_cursor.y = glyph_row->y;
+  w->phys_cursor.hpos = hpos;
+  w->phys_cursor.vpos = vpos;
+  w->phys_cursor_type = cursor_type;
+  w->phys_cursor_ascent = glyph_row->ascent;
+  w->phys_cursor_height = glyph_row->height;
+  w->phys_cursor_width = cursor_width;
+  int fringe_bitmap = NO_FRINGE_BITMAP;
+  int face_id = DEFAULT_FACE_ID;
+  if (!remove_p
+      && flavor == MC_OVERLAY_ARROW_BITMAP
+      && !hscl_all_temp_p
+      && !hscl_temp_p
+      && !hscl_perm_p
+      && !hscl_all_perm_0_p
+      && !hscl_all_perm_1_p
+      && !hscl_all_perm_2_p)
+    {
+      enum face_id overlay_arrow_face_id =
+        (!active_p
+         && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+        ? lookup_named_face (w, f, intern ("+-overlay-arrow-inactive-face"), true)
+        : (active_p
+           && minimal_p)
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-minimal-face"), true)
+        : (active_p
+           && !minimal_p)
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-face"), true)
+        : DEFAULT_FACE_ID;
+      face_id = (cursor_type == LEFT_FRINGE_BITMAP)
+                ? overlay_arrow_face_id
+                : DEFAULT_FACE_ID;
+      glyph_row->left_fringe_face_id = face_id;
+      /* fringe_bitmap = mc_get_logical_fringe_bitmap (w, Qoverlay_arrow, false, false); */
+      if (w->hscroll != 0)
+        fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-overlay-arrow"), false, true);
+        else
+          fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-overlay-arrow"), true, true);
+      /* As to `glyph_row->overlay_arrow_bitmap`, the face may be changed using
+      the `face-remapping-alist' so long as we have a Lisp setting of:
+        (set-fringe-bitmap-face '+-fringe-right-arrow '+-overlay-arrow-face)
+      If we use `glyph_row->left_fringe_bitmap`, then the face may be set using
+      BOTH the `face-remapping-alist' and `glyph_row->left_fringe_face_id`.  In
+      that situation, a Lisp setting of `set-fringe-bitmap-face' is not needed.
+      `draw_fringe_bitmap_1' is somewhat confusing and required stderr messages
+      to see that `glyph_row->overlay_arrow_bitmap` satisfies the first condition
+      of (which != NO_FRINGE_BITMAP).  At this time, @lawlist prefers not to
+      rely upon a Lisp setting using `set-fringe-bitmap-face'. */
+      glyph_row->left_fringe_bitmap = (cursor_type == LEFT_FRINGE_BITMAP)
+                                        ? fringe_bitmap
+                                        : NO_FRINGE_BITMAP;
+      glyph_row->left_fringe_offset = 0;
+      draw_fringe_bitmap (w, glyph_row, true);
+    }
+    else if (!remove_p
+             && flavor == MC_OVERLAY_ARROW_BITMAP
+             && (hscl_all_temp_p
+                 || hscl_all_perm_0_p
+                 || hscl_all_perm_1_p
+                 || hscl_all_perm_2_p
+                 || hscl_temp_p
+                 || hscl_perm_p))
+      {
+        enum face_id overlay_arrow_face_id =
+          (!active_p
+           && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-inactive-face"), true)
+          : (active_p
+             && minimal_p)
+            ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-minimal-face"), true)
+          : (active_p
+             && !minimal_p)
+            ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-face"), true)
+          : DEFAULT_FACE_ID;
+        face_id = (cursor_type == LEFT_FRINGE_BITMAP)
+                  ? overlay_arrow_face_id
+                  : DEFAULT_FACE_ID;
+        glyph_row->left_fringe_face_id = face_id;
+        if (hscl_all_perm_0_p)
+          fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-perm"), false, false);
+          else if (hscl_all_perm_1_p)
+            fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-perm"), true, false);
+            else if (hscl_all_perm_2_p)
+              fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-perm"), false, true);
+              else if (hscl_perm_p)
+                fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-perm"), true, true);
+                else if (hscl_all_temp_p)
+                  fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-temp"), false, false);
+                  else if (hscl_temp_p)
+                    fringe_bitmap = mc_get_logical_fringe_bitmap (w, intern ("+-hscl-temp"), true, false);
+        /* As to `glyph_row->overlay_arrow_bitmap`, the face may be changed using
+        the `face-remapping-alist' so long as we have a Lisp setting of:
+          (set-fringe-bitmap-face '+-fringe-right-arrow '+-overlay-arrow-face)
+        If we use `glyph_row->left_fringe_bitmap`, then the face may be set using
+        BOTH the `face-remapping-alist' and `glyph_row->left_fringe_face_id`.  In
+        that situation, a Lisp setting of `set-fringe-bitmap-face' is not needed.
+        `draw_fringe_bitmap_1' is somewhat confusing and required stderr messages
+        to see that `glyph_row->overlay_arrow_bitmap` satisfies the first condition
+        of (which != NO_FRINGE_BITMAP).  At this time, @lawlist prefers not to
+        rely upon a Lisp setting using `set-fringe-bitmap-face'. */
+        glyph_row->left_fringe_bitmap = (cursor_type == LEFT_FRINGE_BITMAP)
+                                          ? fringe_bitmap
+                                          : NO_FRINGE_BITMAP;
+        glyph_row->left_fringe_offset = 0;
+        draw_fringe_bitmap (w, glyph_row, true);
+      }
+      else if (!remove_p
+               && (flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   || flavor == MC_HOLLOW_RECTANGLE
+                   || flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+                   || flavor == MC_VERTICAL_BAR
+                   || flavor == MC_VERTICAL_BAR_BACKSLASH))
+        {
+          Lisp_Object bitmap_flavor = (flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW)
+                                      ? Qmc_hollow_rectangle_right_arrow
+                                      : (flavor == MC_HOLLOW_RECTANGLE)
+                                        ? Qmc_hollow_rectangle
+                                      : (flavor == MC_VERTICAL_BAR_RIGHT_ARROW)
+                                        ? Qmc_vertical_bar_right_arrow
+                                      : (flavor == MC_VERTICAL_BAR)
+                                        ? Qmc_vertical_bar
+                                      : (flavor == MC_VERTICAL_BAR_BACKSLASH)
+                                        ? Qmc_vertical_bar_backslash
+                                      : Qnil;
+          fringe_bitmap = (cursor_type == RIGHT_FRINGE_BITMAP)
+                          ? lookup_fringe_bitmap (bitmap_flavor)
+                          : NO_FRINGE_BITMAP;
+          face_id = (cursor_type == RIGHT_FRINGE_BITMAP)
+                    ? lookup_named_face (w, f, intern ("+-vertical-bar-face"), true)
+                    : DEFAULT_FACE_ID;
+          glyph_row->cursor_in_fringe_p = false;
+          glyph_row->fringe_bitmap_periodic_p = 0;
+          glyph_row->right_fringe_bitmap = fringe_bitmap;
+          glyph_row->right_fringe_face_id = face_id;
+          glyph_row->right_fringe_offset = 0;
+          draw_fringe_bitmap (w, glyph_row, false);
+        }
+        else if (flavor == MC_GLYPH
+                 || flavor == MC_GLYPHLESS
+                 || flavor == MC_GLYPH_TAB)
+          {
+            w->mc.h = h;
+            w->mc.fx = fx;
+            w->mc.fy = fy;
+            w->mc.glyph_flavor = flavor;
+            w->mc.red = XFLOAT_DATA (AREF (color_vector, 0));
+            w->mc.green = XFLOAT_DATA (AREF (color_vector, 1));
+            w->mc.blue = XFLOAT_DATA (AREF (color_vector, 2));
+            w->mc.posint = posint;
+            /* Some of these values come through as 1.003906, which causes a breakage
+            of the colors in that multiplication by the base will exceed the base. */
+            if (w->mc.red > 1.0)
+              w->mc.red = 1.0;
+            if (w->mc.green > 1.0)
+              w->mc.green = 1.0;
+            if (w->mc.blue > 1.0)
+              w->mc.blue = 1.0;
+            FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y, cursor_type,
+                                               cursor_width, true, active_p);
+            w->mc.h = -1;
+            w->mc.fx = -1;
+            w->mc.fy = -1;
+            w->mc.glyph_flavor = NO_FLAVOR;
+            w->mc.red = -1.0;
+            w->mc.green = -1.0;
+            w->mc.blue = -1.0;
+            w->mc.posint = -1;
+          }
+  /* Restore the previous values for w->phys_cursor and glyph_row. */
+  w->phys_cursor_on_p = phys_cursor_on_p;
+  w->phys_cursor.x = phys_cursor_x;
+  w->phys_cursor.y = phys_cursor_y;
+  w->phys_cursor.hpos = phys_cursor_hpos;
+  w->phys_cursor.vpos = phys_cursor_vpos;
+  w->phys_cursor_type = phys_cursor_type;
+  glyph_row->cursor_in_fringe_p = cursor_in_fringe_p;
+  glyph_row->reversed_p = reversed_p;
+  w->phys_cursor_ascent = phys_cursor_ascent;
+  w->phys_cursor_height = phys_cursor_height;
+  w->phys_cursor_width = phys_cursor_width;
+}
+
+/* Dump contents of glyph GLYPH to stderr.  ROW and AREA are
+   the glyph row and area where the glyph comes from.  */
+
+void
+mc_dump_glyph (struct glyph_row *row, struct glyph *glyph, int area, int relative_x)
+{
+  Lisp_Object character = (CHARACTERP (make_fixnum (glyph->u.ch)))
+                          ? Fchar_to_string (make_fixnum (glyph->u.ch))
+                          : Qnil;
+  if (glyph->type == CHAR_GLYPH
+      || glyph->type == GLYPHLESS_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        (glyph->type == CHAR_GLYPH
+         ? 'C'
+         : 'G'),
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        glyph->u.ch,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        ((!NILP (character)
+         && glyph->u.ch == 9)
+           ? "\\t"
+         : (!NILP (character)
+            && glyph->u.ch == 10)
+           ? "\\n"
+         : (!NILP (character)
+            && glyph->u.ch == 32)
+           ? "\\s"
+         : (!NILP (character)
+            && glyph->u.ch != 9
+            && glyph->u.ch != 10
+            && glyph->u.ch != 32)
+           ? SSDATA (character)
+         : "\\?"));
+    }
+  else if (glyph->type == STRETCH_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'S',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        0u,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        "\\S");
+    }
+  else if (glyph->type == IMAGE_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'I',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.img_id,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+    }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        '+',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.cmp.id);
+      fprintf (stderr, " %4d %1.1d%1.1d",
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p);
+      if (glyph->u.cmp.automatic)
+        fprintf (stderr, " %5d %4d  %3d  %3d %s . [%d-%d]\n",
+                         glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+                         glyph->slice.cmp.from, glyph->slice.cmp.to);
+        else
+        fprintf (stderr, "\n");
+    }
+  else if (glyph->type == XWIDGET_GLYPH)
+    {
+#ifndef HAVE_XWIDGETS
+      eassume (false);
+#else
+      fprintf (stderr,
+        "  %5d/%-5d %5d %4c %6d %c %3d 0x%05x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'X',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+           ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+         : '-')),
+        glyph->pixel_width,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->u.xwidget,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+#endif
+    }
+}
+
+/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
+   GLYPHS 0 means don't show glyph contents.
+   GLYPHS 1 means show glyphs in short form
+   GLYPHS > 1 means show glyphs in long form.  */
+
+void
+mc_dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
+{
+  int relative_x = 0;
+  if (glyphs != 1)
+    {
+      fprintf (stderr, "\nDUMP GLYPH ROW\n");
+      fprintf (stderr, "Row     Start       End Used oE><\\CTZFesm     X    Y    W    H    V    A    P\n");
+      fprintf (stderr, "==============================================================================\n");
+      fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
+%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d  %4d %4d %4d %4d %4d %4d %4d\n",
+         vpos,
+         MATRIX_ROW_START_CHARPOS (row),
+         MATRIX_ROW_END_CHARPOS (row),
+         row->used[TEXT_AREA],
+         row->contains_overlapping_glyphs_p,
+         row->enabled_p,
+         row->truncated_on_left_p,
+         row->truncated_on_right_p,
+         row->continued_p,
+         MATRIX_ROW_CONTINUATION_LINE_P (row),
+         MATRIX_ROW_DISPLAYS_TEXT_P (row),
+         row->ends_at_zv_p,
+         row->fill_line_p,
+         row->ends_in_middle_of_char_p,
+         row->starts_in_middle_of_char_p,
+         row->mouse_face_p,
+         row->x,
+         row->y,
+         row->pixel_width,
+         row->height,
+         row->visible_height,
+         row->ascent,
+         row->phys_ascent);
+      /* The next 3 lines should align to "Start" in the header.  */
+      fprintf (stderr, "    %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
+         row->end.overlay_string_index,
+         row->continuation_lines_width);
+      fprintf (stderr, "    %9"pD"d %9"pD"d\n",
+         CHARPOS (row->start.string_pos),
+         CHARPOS (row->end.string_pos));
+      fprintf (stderr, "    %9d %9d\n", row->start.dpvec_index,
+         row->end.dpvec_index);
+    }
+  if (glyphs > 1)
+    {
+      int area;
+      for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+  {
+    struct glyph *glyph = row->glyphs[area];
+    struct glyph *glyph_end = glyph + row->used[area];
+    /* Glyph for a line end in text.  */
+    if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
+      ++glyph_end;
+    if (glyph < glyph_end)
+      fprintf (stderr, "Glyph#/Total Rel.X T       Pos O   W     Code Face LR     X    Y HPOS VPOS ZV C\n");
+    for (; glyph < glyph_end; ++glyph)
+      {
+        mc_dump_glyph (row, glyph, area, relative_x);
+        relative_x += glyph->pixel_width;
+      }
+  }
+    }
+  else if (glyphs == 1)
+    {
+      int area;
+      char s[SHRT_MAX + 4];
+      for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+  {
+    int i;
+    for (i = 0; i < row->used[area]; ++i)
+      {
+        struct glyph *glyph = row->glyphs[area] + i;
+        if (i == row->used[area] - 1
+      && area == TEXT_AREA
+      && NILP (glyph->object)
+      && glyph->type == CHAR_GLYPH
+      && glyph->u.ch == ' ')
+    {
+      strcpy (&s[i], "[\\n]");
+      i += 4;
+    }
+        else if (glyph->type == CHAR_GLYPH
+           && glyph->u.ch < 0x80
+           && glyph->u.ch >= ' ')
+    s[i] = glyph->u.ch;
+        else
+    s[i] = '.';
+      }
+    s[i] = '\0';
+    fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
+  }
+    }
+}
+
+DEFUN ("mc-dump-glyph-row", Fmc_dump_glyph_row, Smc_dump_glyph_row, 1, 2, "P",
+       doc: /* Dump glyph row ROW to stderr.
+Interactively, ROW is the prefix numeric argument and defaults to
+the row which displays point.
+Optional argument GLYPHS 0 means don't dump glyphs.
+GLYPHS 1 means dump glyphs in short form.
+GLYPHS > 1 or omitted means dump glyphs in long form.  */)
+  (Lisp_Object row, Lisp_Object glyphs)
+{
+  struct window *w = XWINDOW (selected_window);
+  struct glyph_matrix *matrix;
+  EMACS_INT vpos;
+  if (NILP (row))
+    {
+      int d1, d2, d3, d4, d5, ypos;
+      bool visible_p = pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &ypos);
+      int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+      int voffset = (header_line_height > 0
+                     && ypos > 0)
+                      ? ypos + 1
+                      : ypos;
+      if (visible_p)
+        vpos = voffset;
+        else
+          vpos = 0;
+    }
+    else
+      {
+        CHECK_NUMBER (row);
+        vpos = XFIXNUM (row);
+      }
+  matrix = w->current_matrix;
+  if (vpos >= 0 && vpos < matrix->nrows)
+    mc_dump_glyph_row (MATRIX_ROW (matrix, vpos),
+        vpos,
+        TYPE_RANGED_FIXNUMP (int, glyphs) ? XFIXNUM (glyphs) : 2);
+  return Qnil;
+}
+
+void
+mc_dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
+{
+  int i;
+  for (i = 0; i < matrix->nrows; ++i)
+    mc_dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
+}
+
+DEFUN ("mc-dump-glyph-matrix", Fmc_dump_glyph_matrix,
+       Smc_dump_glyph_matrix, 0, 1, "p",
+       doc: /* Dump the current matrix of the selected window to stderr.
+Shows contents of glyph row structures.  With non-nil
+parameter GLYPHS, dump glyphs as well.  If GLYPHS is 1 show
+glyphs in short form, otherwise show glyphs in long form.
+
+Interactively, no argument means show glyphs in short form;
+with numeric argument, its value is passed as the GLYPHS flag.  */)
+  (Lisp_Object glyphs)
+{
+  struct window *w = XWINDOW (selected_window);
+  struct buffer *buffer = XBUFFER (w->contents);
+
+  fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
+	   BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
+  fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
+	   w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
+  fprintf (stderr, "=============================================\n");
+  mc_dump_glyph_matrix (w->current_matrix,
+		     TYPE_RANGED_FIXNUMP (int, glyphs) ? XFIXNUM (glyphs) : 0);
+  return Qnil;
+}
+
+static void
+mc_helper (struct window *w, int x, int fx, int y, int fy, int hpos,
+           int vpos, int h, enum text_cursor_kinds cursor_type, int cursor_width,
+           Lisp_Object foreground, Lisp_Object background, bool active_p,
+           bool minimal_p, int flavor, int posint, Lisp_Object *result)
+{
+  bool mc_stderr_p = !NILP (BVAR (current_buffer, mc_stderr));
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+  char *window_char = SSDATA (window_string);
+  double red_fg = XFLOAT_DATA (AREF (foreground, 0));
+  double green_fg = XFLOAT_DATA (AREF (foreground, 1));
+  double blue_fg = XFLOAT_DATA (AREF (foreground, 2));
+  if (red_fg > 1.0)
+    red_fg = 1.0;
+  if (green_fg > 1.0)
+    green_fg = 1.0;
+  if (blue_fg > 1.0)
+    blue_fg = 1.0;
+  double red_bg = XFLOAT_DATA (AREF (background, 0));
+  double green_bg = XFLOAT_DATA (AREF (background, 1));
+  double blue_bg = XFLOAT_DATA (AREF (background, 2));
+  if (red_bg > 1.0)
+    red_bg = 1.0;
+  if (green_bg > 1.0)
+    green_bg = 1.0;
+  if (blue_bg > 1.0)
+    blue_bg = 1.0;
+  if (mc_stderr_p)
+    fprintf (stderr, "\nmc_helper (%s):\n\
+  x (%d) | fx (%d) | y (%d) | fy (%d) | hpos (%d) | vpos (%d) | h (%d)\n\
+  cursor_type (%s) | cursor_width (%d) | active_p (%s)\n\
+  minimal_p (%s) | flavor (%s) | posint (%d)\n\
+  FG-RGB (%f/%f/%f) | BG-RGB (%f/%f/%f)\n",
+  window_char,
+  x, fx, y, fy, hpos, vpos, h,
+  SSDATA (Fprin1_to_string (mc_cursor_type_to_lisp (cursor_type), Qnil)),
+  cursor_width,
+  (active_p ? "true" : "false"),
+  (minimal_p ? "true" : "false"),
+  (flavor == NO_FLAVOR
+      ? "NO_FLAVOR"
+    : flavor == MC_GLYPH
+      ? "MC_GLYPH"
+    : flavor == MC_GLYPHLESS
+      ? "MC_GLYPHLESS"
+    : flavor == MC_GLYPH_TAB
+      ? "MC_GLYPH_TAB"
+    : flavor == MC_OVERLAY_ARROW_BITMAP
+      ? "MC_OVERLAY_ARROW_BITMAP"
+    : flavor == MC_PILCROW
+      ? "MC_PILCROW"
+    : flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW
+      ? "MC_HOLLOW_RECTANGLE_RIGHT_ARROW"
+    : flavor == MC_HOLLOW_RECTANGLE
+      ? "MC_HOLLOW_RECTANGLE"
+    : flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+      ? "MC_VERTICAL_BAR_RIGHT_ARROW"
+    : flavor == MC_VERTICAL_BAR
+      ? "MC_VERTICAL_BAR"
+    : flavor == MC_VERTICAL_BAR_BACKSLASH
+      ? "MC_VERTICAL_BAR_BACKSLASH"
+    : "OOPS"),
+  posint,
+  red_fg, green_fg, blue_fg, red_bg, green_bg, blue_bg);
+  bool remove_p = false;
+  mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                        cursor_width, foreground, active_p, minimal_p,
+                        flavor, posint, remove_p);
+  Lisp_Object fifteen_elements = listn (CONSTYPE_HEAP, 15,
+                                         make_fixnum (x),
+                                         make_fixnum (fx),
+                                         make_fixnum (y),
+                                         make_fixnum (fy),
+                                         make_fixnum (hpos),
+                                         make_fixnum (vpos),
+                                         make_fixnum (h),
+                                         mc_cursor_type_to_lisp (cursor_type),
+                                         make_fixnum (cursor_width),
+                                         foreground,
+                                         background,
+                                         make_fixnum (active_p),
+                                         make_fixnum (minimal_p),
+                                         make_fixnum (flavor),
+                                         make_fixnum (posint));
+  *result = Fcons (fifteen_elements, *result);
+}
+
+/* Return a pointer to the glyph W's physical cursor is on.  Value is
+   null if W's current matrix is invalid, so that no meaningful glyph
+   can be returned.  */
+
+struct glyph *
+mc_get_phys_cursor_glyph (struct window *w, int x, int hpos, int vpos)
+{
+  struct glyph_row *row;
+  struct glyph *glyph;
+  if (!(vpos >= 0
+        && vpos < w->current_matrix->nrows))
+    return NULL;
+  row = MATRIX_ROW (w->current_matrix, vpos);
+  if (!row->enabled_p)
+    return 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 (!row->reversed_p && hpos < 0)
+        hpos = 0;
+      if (row->reversed_p && hpos >= row->used[TEXT_AREA])
+        hpos = row->used[TEXT_AREA] - 1;
+    }
+  if (0 <= hpos && hpos < row->used[TEXT_AREA])
+    glyph = row->glyphs[TEXT_AREA] + hpos;
+    else
+      glyph = NULL;
+  return glyph;
+}
+
+/* MULTIPLE_CURSORS:  We do not use this function.
+   HORIZONTAL_RULER:  We want a universal fy coordinate for a level ruler.
+   VERTICAL_RULER:  We want an h that ensures no gap between previous/next line.
+                    The fx coordinate is set elsewhere based upon opoint_x. */
+
+void
+mc_get_phys_cursor_geometry (struct window *w, struct glyph_row *glyph_row,
+                             int x, int *fx, int y, int *fy, int hpos,
+                             int vpos, int *h, enum text_cursor_kinds cursor_type,
+                             int cursor_width, int *wd)
+{
+  struct glyph *fake_phys_cursor_glyph = mc_get_phys_cursor_glyph (w, x, hpos, vpos);
+  if (fake_phys_cursor_glyph != NULL)
+    {
+      struct frame *f = XFRAME (WINDOW_FRAME (w));
+      int h_temp, h0, y0, ascent;
+      /* Compute the width of the rectangle to draw.  If on a stretch
+         glyph, and `x-stretch-block-cursor' is nil, don't draw a
+         rectangle as wide as the glyph, but use a canonical character
+         width instead.  */
+      *wd = scratch_glyphs->pixel_width;
+      if (x < 0)
+        {
+          *wd += x;
+          x = 0;
+        }
+      if (scratch_glyphs->type == STRETCH_GLYPH
+          && !x_stretch_cursor_p)
+        *wd = min (FRAME_COLUMN_WIDTH (f), *wd);
+      /* Don't let the hollow cursor glyph descend below the glyph row's
+         ascent value, lest the hollow cursor looks funny.  */
+      ascent = glyph_row->ascent;
+      if (glyph_row->ascent < scratch_glyphs->ascent)
+        {
+          y -= scratch_glyphs->ascent - glyph_row->ascent;
+          ascent = scratch_glyphs->ascent;
+        }
+      /* If y is below window bottom, ensure that we still see a cursor.
+      As to FRAME_LINE_HEIGHT versus glyph_row->visible_height, prefer the MAX. */
+      h0 = max (FRAME_LINE_HEIGHT (f), glyph_row->visible_height);
+      h_temp = max (h0, ascent + scratch_glyphs->descent);
+      h0 = min (h0, ascent + scratch_glyphs->descent);
+      y0 = WINDOW_HEADER_LINE_HEIGHT (w);
+      if (y < y0)
+        {
+          h_temp = max (h_temp - (y0 - y) + 1, h0);
+          y = y0 - 1;
+        }
+      else
+        {
+          y0 = window_text_bottom_y (w) - h0;
+          if (y > y0)
+            {
+              h_temp += y - y0;
+              y = y0;
+            }
+        }
+      *fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+      *fy = WINDOW_TO_FRAME_PIXEL_Y (w, y);
+      *h = h_temp;
+      if (cursor_type == HBAR_CURSOR)
+        {
+          int cursor_height = (cursor_width < 1) ? lrint (0.25 * *h) : cursor_width;
+          if (cursor_height > glyph_row->height)
+            cursor_height = glyph_row->height;
+          if (*h > cursor_height)
+            *fy += *h - cursor_height;
+          *h = cursor_height;
+        }
+    }
+}
+
+/* Return the start or end position of the region.
+   BEGINNINGP means return the start.
+   If there is no region active, signal an error.
+   EXAMPLE (region-beginning):  region_limit (1)
+   EXAMPLE (region-end):  region_limit (0) */
+
+static Lisp_Object
+mc_region_limit (bool beginningp)
+{
+  Lisp_Object m;
+  if (!NILP (Vtransient_mark_mode)
+      && NILP (Vmark_even_if_inactive)
+      && NILP (BVAR (current_buffer, mark_active)))
+    return Qnil;
+  m = Fmarker_position (BVAR (current_buffer, mark));
+  if (NILP (m))
+    return Qnil;
+  /* See `region-active-p' and `redisplay--update-region-highlight'. */
+  if (!NILP (Vtransient_mark_mode)
+      && !NILP (BVAR (current_buffer, mark_active))
+      && !NILP (m))
+    return make_fixnum ((PT < XFIXNAT (m)) == beginningp
+                        ? PT
+                        : clip_to_bounds (BEGV, XFIXNAT (m), ZV));
+      else
+        return Qnil;
+}
+
+void
+mc_engine (struct glyph_row *row, struct glyph *glyph, int area, int relative_x,
+            struct window *w, ptrdiff_t posint, enum text_cursor_kinds cursor_type,
+            int cursor_width, Lisp_Object foreground, bool active_p,
+            bool minimal_p, enum type_of_action action_type, Lisp_Object *result)
+{
+  bool mc_stderr_p = !NILP (BVAR (current_buffer, mc_stderr));
+  int opoint_x = w->output_cursor.x;
+  int opoint_y = w->output_cursor.y;
+  int opoint_hpos = w->output_cursor.hpos;
+  int opoint_vpos = w->output_cursor.vpos;
+  Lisp_Object character = (CHARACTERP (make_fixnum (glyph->u.ch)))
+                          ? Fchar_to_string (make_fixnum (glyph->u.ch))
+                          : Qnil;
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  int text_area_width = window_box_width (w, TEXT_AREA);
+  int frame_char_width = FRAME_COLUMN_WIDTH (f);
+  bool fill_column_p = !NILP (BVAR (b, fill_column));
+  int fill_col = XFIXNUM (BVAR (b, fill_column));
+  int fill_column_x = (fill_column_p)
+                      ? fill_col * frame_char_width
+                      : 0;
+  int temp_x = relative_x;
+  int temp_y = row->y;
+  int temp_hpos = glyph - row->glyphs[TEXT_AREA];
+  int temp_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+  int temp_face_id = glyph->face_id;
+  int temp_charpos = glyph->charpos;
+
+/* --------------------------------------------------------------------------- */
+/*                       BEGIN:  CHAR_GLYPH | GLYPHLESS_GLYPH                  */
+/* --------------------------------------------------------------------------- */
+  if (glyph->type == CHAR_GLYPH
+      || glyph->type == GLYPHLESS_GLYPH)
+  {
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        (glyph->type == CHAR_GLYPH
+         ? 'C'
+         : 'G'),
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+              glyph->pixel_width,
+        glyph->u.ch,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        ((!NILP (character)
+         && glyph->u.ch == 9)
+           ? "\\t"
+         : (!NILP (character)
+            && glyph->u.ch == 10)
+           ? "\\n"
+         : (!NILP (character)
+            && glyph->u.ch == 32)
+           ? "\\s"
+         : (!NILP (character)
+            && glyph->u.ch != 9
+            && glyph->u.ch != 10
+            && glyph->u.ch != 32)
+           ? SSDATA (character)
+         : "\\?"));
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*               MULTIPLE_CURSORS:  CHAR_GLYPH | GLYPHLESS_GLYPH               */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               HORIZONTAL_RULER:  CHAR_GLYPH | GLYPHLESS_GLYPH               */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      bool real_fake_cursor_p = (opoint_x == relative_x
+                                 && opoint_hpos == temp_hpos
+                                 && opoint_y == glyph->y
+                                 && opoint_vpos == temp_vpos);
+      int _fx, fy, _h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &fy, temp_hpos, temp_vpos,
+                                   &_h, cursor_type, cursor_width, &_wd);
+      if (temp_x <= text_area_width
+          && !real_fake_cursor_p)
+        mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                   -1, cursor_type, cursor_width, foreground,
+                   mc_bg_lsl (w, temp_face_id), active_p,
+                   minimal_p, MC_GLYPH, temp_charpos, result);
+      /* It is possible to use MC_GLYPH and adjust the fx coordinate; however,
+      the middle-dot / space glyph on a word-wrapped line will be overwritten
+      numerous times and is unsightly. */
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1)
+        {
+          int _fx, fy, _h, _wd;
+          mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                       temp_y, &fy, temp_hpos, temp_vpos,
+                                       &_h, cursor_type, cursor_width, &_wd);
+          temp_x += glyph->pixel_width;
+          while (temp_x <= text_area_width)
+            {
+              mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                         -1, cursor_type, cursor_width, foreground,
+                         mc_bg_lsl (w, temp_face_id), active_p,
+                         minimal_p, MC_GLYPHLESS, temp_charpos, result);
+              /* `w->phys_cursor_width` is determined by `glyph->pixel_width`,
+              and the space appended to a line ending in EOL is not necessarily
+              the same as the frame-char-width; e.g., variable with font.  Thus,
+              we must use the `glyph->pixel_width` to avoid blank spaces between
+              the floating hbar fake cursors. */
+              temp_x += glyph->pixel_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               VERTICAL_RULER:  CHAR_GLYPH | GLYPHLESS_GLYPH                 */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && opoint_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      int temp_x = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                    && opoint_x > relative_x)
+                    ? opoint_x
+                    : relative_x;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, opoint_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               FILL_COLUMN:  CHAR_GLYPH | GLYPHLESS_GLYPH                 */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fill_column_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : (!NILP (BVAR (b, crosshairs))
+                      && !NILP (BVAR (XBUFFER (w->contents), crosshairs_vertical_ruler))
+                      && opoint_y == temp_y
+                      && opoint_vpos == temp_vpos)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      int temp_x = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                    && fill_column_x > relative_x)
+                    ? fill_column_x
+                    : relative_x;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, fill_column_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                        END:  CHAR_GLYPH | GLYPHLESS_GLYPH                   */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                             BEGIN:  STRETCH_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == STRETCH_GLYPH)
+  {
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'S',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        0u,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        "\\S");
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                        HORIZONTAL_RULER:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      bool real_fake_cursor_p = (opoint_x == relative_x
+                                 && opoint_hpos == temp_hpos
+                                 && opoint_y == glyph->y
+                                 && opoint_vpos == temp_vpos);
+      int _fx, fy, _h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &fy, temp_hpos, temp_vpos,
+                                   &_h, cursor_type, cursor_width, &_wd);
+      if (temp_x <= text_area_width
+          && !real_fake_cursor_p)
+        while (temp_x < relative_x + glyph->pixel_width)
+          {
+            mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                       -1, cursor_type, cursor_width, foreground,
+                       mc_bg_lsl (w, temp_face_id), active_p,
+                       minimal_p, MC_GLYPH_TAB, temp_charpos, result);
+            temp_x += frame_char_width;
+          }
+        else if (temp_x + glyph->pixel_width < text_area_width
+                 && real_fake_cursor_p
+                 && glyph->pixel_width > frame_char_width)
+          {
+            temp_x += frame_char_width;
+            while (temp_x < relative_x + glyph->pixel_width)
+              {
+                mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                           -1, cursor_type, cursor_width, foreground,
+                           mc_bg_lsl (w, temp_face_id), active_p,
+                           minimal_p, MC_GLYPH_TAB, temp_charpos, result);
+                temp_x += frame_char_width;
+              }
+          }
+      /* It is possible to use MC_GLYPH and adjust the fx coordinate; however,
+      the middle-dot / space glyph on a word-wrapped line will be overwritten
+      numerous times and is unsightly. */
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1)
+        {
+          int _fx, fy, _h, _wd;
+          mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                       temp_y, &fy, temp_hpos, temp_vpos,
+                                       &_h, cursor_type, cursor_width, &_wd);
+          /* temp_x += glyph->pixel_width; */
+          while (temp_x <= text_area_width)
+            {
+              mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                         -1, cursor_type, cursor_width, foreground,
+                         mc_bg_lsl (w, temp_face_id), active_p,
+                         minimal_p, MC_GLYPHLESS, temp_charpos, result);
+              temp_x += frame_char_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          VERTICAL_RULER:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && opoint_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH_TAB;
+      int temp_x = opoint_x;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, opoint_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          FILL_COLUMN:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fill_column_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : (!NILP (BVAR (b, crosshairs))
+                      && !NILP (BVAR (XBUFFER (w->contents), crosshairs_vertical_ruler))
+                      && opoint_y == temp_y
+                      && opoint_vpos == temp_vpos)
+                     ? MC_GLYPH_TAB
+                   : MC_GLYPH_TAB;
+      int temp_x = fill_column_x;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, fill_column_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                               END:  STRETCH_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                              BEGIN:  IMAGE_GLYPH                            */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == IMAGE_GLYPH)
+  {
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'I',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.img_id,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                         MULTIPLE_CURSORS:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      cursor_type = HOLLOW_BOX_CURSOR;
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                         HORIZONTAL_RULER:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      cursor_type = HOLLOW_BOX_CURSOR;
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           VERTICAL_RULER:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      cursor_type = HOLLOW_BOX_CURSOR;
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           FILL_COLUMN:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      cursor_type = HOLLOW_BOX_CURSOR;
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                                END:  IMAGE_GLYPH                            */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                            BEGIN:  COMPOSITE_GLYPH                          */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == COMPOSITE_GLYPH)
+  {
+    if (mc_stderr_p)
+      {
+        fprintf (stderr,
+          "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x",
+          glyph - row->glyphs[TEXT_AREA],
+          ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+          relative_x,
+          '+',
+          glyph->charpos,
+          (BUFFERP (glyph->object)
+           ? 'B'
+           : (STRINGP (glyph->object)
+              ? 'S'
+              : (NILP (glyph->object)
+                 ? '0'
+                 : '-'))),
+          glyph->pixel_width,
+          (unsigned int) glyph->u.cmp.id);
+        fprintf (stderr, " %4d %1.1d%1.1d",
+          glyph->face_id,
+          glyph->left_box_line_p,
+          glyph->right_box_line_p);
+      if (glyph->u.cmp.automatic)
+        fprintf (stderr, " %5d %4d  %3d  %3d %s . [%d-%d]\n",
+                         glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+                         glyph->slice.cmp.from, glyph->slice.cmp.to);
+        else
+          fprintf (stderr, "\n");
+      }
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                       MULTIPLE_CURSORS:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                       HORIZONTAL_RULER:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      bool real_fake_cursor_p = (opoint_x == relative_x
+                                 && opoint_hpos == temp_hpos
+                                 && opoint_y == glyph->y
+                                 && opoint_vpos == temp_vpos);
+      int _fx, fy, _h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &fy, temp_hpos, temp_vpos,
+                                   &_h, cursor_type, cursor_width, &_wd);
+      if (temp_x <= text_area_width
+          && !real_fake_cursor_p)
+        mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                   -1, cursor_type, cursor_width, foreground,
+                   mc_bg_lsl (w, temp_face_id), active_p,
+                   minimal_p, MC_GLYPH, temp_charpos, result);
+      /* It is possible to use MC_GLYPH and adjust the fx coordinate; however,
+      the middle-dot / space glyph on a word-wrapped line will be overwritten
+      numerous times and is unsightly. */
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1)
+        {
+          int _fx, fy, _h, _wd;
+          mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                       temp_y, &fy, temp_hpos, temp_vpos,
+                                       &_h, cursor_type, cursor_width, &_wd);
+          temp_x += glyph->pixel_width;
+          while (temp_x <= text_area_width)
+            {
+              mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                         -1, cursor_type, cursor_width, foreground,
+                         mc_bg_lsl (w, temp_face_id), active_p,
+                         minimal_p, MC_GLYPHLESS, temp_charpos, result);
+              temp_x += frame_char_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                         VERTICAL_RULER:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && opoint_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, opoint_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                         FILL_COLUMN:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fill_column_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : (!NILP (BVAR (b, crosshairs))
+                      && !NILP (BVAR (XBUFFER (w->contents), crosshairs_vertical_ruler))
+                      && opoint_y == temp_y
+                      && opoint_vpos == temp_vpos)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, fill_column_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                              END:  COMPOSITE_GLYPH                          */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                             BEGIN:  XWIDGET_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == XWIDGET_GLYPH)
+  {
+#ifndef HAVE_XWIDGETS
+    eassume (false);
+#else
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n  %5d/%-5d %5d %4c %6d %c %3d 0x%05x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'X',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : '-')),
+        glyph->pixel_width,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->u.xwidget,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+#endif
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, temp_x, -1, temp_y, -1, temp_hpos, temp_vpos,
+                 -1, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, MC_GLYPH, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                        HORIZONTAL_RULER:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      bool real_fake_cursor_p = (opoint_x == relative_x
+                                 && opoint_hpos == temp_hpos
+                                 && opoint_y == glyph->y
+                                 && opoint_vpos == temp_vpos);
+      int _fx, fy, _h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &fy, temp_hpos, temp_vpos,
+                                   &_h, cursor_type, cursor_width, &_wd);
+      if (temp_x <= text_area_width
+          && !real_fake_cursor_p)
+        mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                   -1, cursor_type, cursor_width, foreground,
+                   mc_bg_lsl (w, temp_face_id), active_p,
+                   minimal_p, MC_GLYPH, temp_charpos, result);
+      /* It is possible to use MC_GLYPH and adjust the fx coordinate; however,
+      the middle-dot / space glyph on a word-wrapped line will be overwritten
+      numerous times and is unsightly. */
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1)
+        {
+          int _fx, fy, _h, _wd;
+          mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                       temp_y, &fy, temp_hpos, temp_vpos,
+                                       &_h, cursor_type, cursor_width, &_wd);
+          temp_x += glyph->pixel_width;
+          while (temp_x <= text_area_width)
+            {
+              mc_helper (w, temp_x, -1, temp_y, fy, temp_hpos, temp_vpos,
+                         -1, cursor_type, cursor_width, foreground,
+                         mc_bg_lsl (w, temp_face_id), active_p,
+                         minimal_p, MC_GLYPHLESS, temp_charpos, result);
+              temp_x += frame_char_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          VERTICAL_RULER:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && opoint_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, opoint_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          FILL_COLUMN:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      /* `glyph->charpos` is unreliable when testing for ZV -- without line
+      numbers, the value is -1; with line numbers, the value is _sometimes_ ZV.
+      `glyph->zv_p` is reliable, but relies upon a few core modification.
+      `zv_p` encompasses a couple of situations:  a line ending in ZV, but
+       containing one or more characters before ZV; and, a line beyond ZV that
+       may consist of spaces equal to `it->lnum_pixel_width` / frame_char_width,
+       or just one space if there are no line numbers. */
+      bool zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                   && MATRIX_ROW_END_CHARPOS (row) == ZV);
+      bool cursor_in_fringe_p = opoint_x + glyph->pixel_width >= text_area_width;
+      int flavor = (cursor_in_fringe_p
+                    && row->truncated_on_right_p)
+                     ? MC_VERTICAL_BAR_RIGHT_ARROW
+                   : (cursor_in_fringe_p
+                      && row->continued_p)
+                     ? MC_VERTICAL_BAR_BACKSLASH
+                   : (cursor_in_fringe_p
+                      && !row->truncated_on_right_p
+                      && !row->continued_p)
+                     ? MC_VERTICAL_BAR
+                   : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fill_column_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (zv_p)
+                     ? MC_GLYPHLESS
+                   : (!NILP (BVAR (b, crosshairs))
+                      && !NILP (BVAR (XBUFFER (w->contents), crosshairs_vertical_ruler))
+                      && opoint_y == temp_y
+                      && opoint_vpos == temp_vpos)
+                     ? MC_GLYPHLESS
+                   : MC_GLYPH;
+      if (flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || flavor == MC_VERTICAL_BAR_BACKSLASH
+          || flavor == MC_VERTICAL_BAR)
+        cursor_type = RIGHT_FRINGE_BITMAP;
+      int _fx, _fy, h, _wd;
+      mc_get_phys_cursor_geometry (w, row, temp_x, &_fx,
+                                   temp_y, &_fy, temp_hpos, temp_vpos,
+                                   &h, cursor_type, cursor_width, &_wd);
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, fill_column_x);
+      mc_helper (w, temp_x, fx, temp_y, -1, temp_hpos, temp_vpos,
+                 h, cursor_type, cursor_width, foreground,
+                 mc_bg_lsl (w, temp_face_id), active_p,
+                 minimal_p, flavor, temp_charpos, result);
+      break;
+    }
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                               END:  XWIDGET_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+}
+
+/* MULTIPLE_CURSORS_CACHE:
+-  The first element is compared to the `multiple-cursors-conf' to determine whether we need to
+   recalculate coordinates.  [We also check whether window-start/window-end changed.]
+-  The second element contains all previously calculated coordinates.
+-  The third element is the buffer where the `w->multiple_cursors_cache' was set.  Because the
+   `w->multiple_cursors_cache' is window-local, we need to check both the window and the buffer.
+     (((22 20 2 0 cursor_type cursor_width foreground background active_p flavor posint)
+       (33 20 3 0 cursor_type cursor_width foreground background active_p flavor posint)
+       (44 20 4 0 cursor_type cursor_width foreground background active_p flavor posint)
+       (55 20 5 0 cursor_type cursor_width foreground background active_p flavor posint)
+       (66 20 6 0 cursor_type cursor_width foreground background active_p flavor posint)
+       (77 20 7 0 cursor_type cursor_width foreground background active_p flavor posint))
+      (WINDOW where `w->multiple_cursors_cache' was set.)
+      (BUFFER where `w->multiple_cursors_cache' was set.)) */
+/* If REMOVE is 0, then draw fake cursors.  If REMOVE is 1, then erase fake cursors. */
+
+void
+mc_draw_multiple_cursors (struct window *w, bool active_p, bool minimal_p)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_draw_multiple_cursors (%s)\n", window_char);
+    }
+#endif
+  bool mc_stderr_p = !NILP (BVAR (current_buffer, mc_stderr));
+  ptrdiff_t opoint_pt = PT;
+  int opoint_x = w->phys_cursor.x;
+  int opoint_y = w->phys_cursor.y;
+  int opoint_hpos = w->phys_cursor.hpos;
+  int opoint_vpos = w->phys_cursor.vpos;
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  /* When swiching to another buffer (e.g., a new buffer), `w->contents` may not
+  necessarily be the `current_buffer`.  In such a case, all calculations would
+  be wrong unless `w->contents` is set as the `current_buffer`.  This avoids
+  errors that are time consuming to debug:  break args_out_of_range */
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  /* `start_display' calls `init_iterator' which crashes Emacs if:
+  eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer) && charpos <= ZV))
+  eassert (charpos == BYTE_TO_CHAR (bytepos))
+  This happens when multiple fake cursors are active and the user types:  M-x .... */
+  ptrdiff_t charpos = marker_position (w->start);
+  struct text_pos start_text_position;
+  SET_TEXT_POS_FROM_MARKER (start_text_position, w->start);
+  ptrdiff_t bytepos = BYTEPOS (start_text_position);
+  bool barf_crash_one = (charpos < 0 || (charpos >= BUF_BEG (current_buffer) && charpos <= ZV)) ? false : true;
+  if (barf_crash_one)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  bool barf_crash_two = (charpos == BYTE_TO_CHAR (bytepos)) ? false : true;
+  if (barf_crash_two)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  /* `matrix_row' in `dispnew.c` contains the following tests,
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows); */
+  bool barf_crash_three = (w->current_matrix && w->current_matrix->rows) ? false : true;
+  if (barf_crash_three)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  bool barf_crash_four = (opoint_vpos >= 0 && opoint_vpos < w->current_matrix->nrows) ? false : true;
+  if (barf_crash_four)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  ptrdiff_t posint = -1;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width = 1;
+  Lisp_Object specs, lisp_type, foreground, vlist;
+  Lisp_Object result = Qnil;
+  int header_line_format = WINDOW_HEADER_LINE_HEIGHT (w);
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+/* --------------------------------------------------------------------------- */
+/*                           ERASE THE REAL CURSOR                             */
+/* --------------------------------------------------------------------------- */
+  /* `display_and_set_cursor' properly sets `w->phys_cursor.x/y/hpos/vpos` when
+  the cursor is ON. */
+/* `w->phys_cursor.x/y/hpos/vpos` are incorrect after evaluating (scroll-left 1)
+a couple of times.  Redisplay erases the real cursor almost immediately after
+`mc_draw_crosshairs' runs its course -- almost too quickly to see it happening.
+The character where Emacs thinks the real cursor is located gets redrawn, albiet
+without the real cursor.  Emacs thinks the real cursor is one character to the
+right of where it should be -- this is most likely due to an incorrect HPOS.
+This phenomena does not occur when (scroll-left 1) is called interactively; e.g.,
+horizontal scroll wheel.  Inasmuch as `erase_phys_cursor' updates more than
+merely the aforementioned coordinates, resetting those coordinates after the fact
+is insufficient to fix the problem.  We use `w->output_cursor.x/y/hpos/vpos`
+because those coordinates are correct.  We fix `w->phys_cursor.x/y/hpos/vpos`
+BEFORE calling `erase_phys_cursor' so that other goodies are updated. */
+  if (w->hscroll > 0)
+    {
+      w->phys_cursor.x = w->output_cursor.x;
+      w->phys_cursor.y = w->output_cursor.y;
+      w->phys_cursor.hpos = w->output_cursor.hpos;
+      w->phys_cursor.vpos = w->output_cursor.vpos;
+    }
+  erase_phys_cursor (w);
+/* --------------------------------------------------------------------------- */
+/*                           REPLACE THE REAL CURSOR                           */
+/* --------------------------------------------------------------------------- */
+  ptrdiff_t current_col;
+  bool fill_column_p = !NILP (BVAR (b, fill_column));
+  int fill_col = XFIXNUM (BVAR (b, fill_column));
+  enum face_id even_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-numbered-column-face"), true);
+  struct face *even_face = FACE_FROM_ID (f, even_face_id);
+  Lisp_Object even_color = even_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (even_color);
+  Lisp_Object even_color_vector = mc_color_vector_calc (w, even_color);
+  enum face_id odd_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-numbered-column-face"), true);
+  struct face *odd_face = FACE_FROM_ID (f, odd_face_id);
+  Lisp_Object odd_color = odd_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (odd_color);
+  Lisp_Object odd_color_vector = mc_color_vector_calc (w, odd_color);
+  enum face_id fill_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-beyond-fill-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-beyond-fill-column-face"), true);
+  struct face *fill_face = FACE_FROM_ID (f, fill_face_id);
+  Lisp_Object fill_color = fill_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (fill_color);
+  Lisp_Object fill_color_vector = mc_color_vector_calc (w, fill_color);
+  /* FIXME:  Put in some code to default to HOLLOW_BOX_CURSOR if the user has
+  unwittingly come up with some unacceptable form of unrecognized cursor type. */
+  Lisp_Object cursor_lisp_type = BVAR (b, mc_real_fake_cursor);
+  enum text_cursor_kinds temp_cursor_type = (CONSP (cursor_lisp_type))
+                                             ? mc_lisp_to_cursor_type (XCAR (cursor_lisp_type))
+                                             : mc_lisp_to_cursor_type (cursor_lisp_type);
+  int temp_cursor_width = (CONSP (cursor_lisp_type))
+                           ? XFIXNUM (XCAR (XCDR (cursor_lisp_type)))
+                           : 1;
+  enum face_id cursor_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+  struct face *cursor_face = FACE_FROM_ID (f, cursor_face_id);
+  Lisp_Object cursor_color = cursor_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (cursor_color);
+  current_col = mc_current_column (w, opoint_pt);
+  /* red */
+  if (current_col % 2 != 0
+      && !fill_column_p)
+    foreground = odd_color_vector;
+  /* yellow */
+  if (current_col % 2 == 0
+      && !fill_column_p)
+    foreground = even_color_vector;
+  /* red */
+  if (current_col % 2 != 0
+      && fill_column_p
+      && current_col <= fill_col)
+    foreground = odd_color_vector;
+  /* yellow */
+  if (current_col % 2 == 0
+      && fill_column_p
+      && current_col <= fill_col)
+    foreground = even_color_vector;
+  /* green */
+  if (fill_column_p
+      && current_col > fill_col)
+    foreground = fill_color_vector;
+  Lisp_Object cursor_fg = (active_p)
+                          ? foreground
+                          : mc_color_vector_calc (w, cursor_color);
+  struct glyph *cursor_glyph =
+            mc_get_phys_cursor_glyph (w, opoint_x, opoint_hpos, opoint_vpos);
+  cursor_face_id = (cursor_glyph == NULL)
+                    ? DEFAULT_FACE_ID
+                    : cursor_glyph->face_id;
+  mc_helper (w, opoint_x, -1, opoint_y, -1, opoint_hpos, opoint_vpos,
+             -1, temp_cursor_type, temp_cursor_width, cursor_fg,
+             mc_bg_lsl (w, cursor_face_id), active_p,
+             minimal_p, MC_GLYPH, opoint_pt, &result);
+/* --------------------------------------------------------------------------- */
+/*                        DRAW / RECORD MULTIPLE CURSORS                       */
+/* --------------------------------------------------------------------------- */
+  for (vlist = BVAR (b, multiple_cursors_conf);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      specs = XCAR (vlist);
+      posint = XFIXNUM (Fnth (make_fixnum (0), specs));
+      lisp_type = Fnth (make_fixnum (1), specs);
+      if (CONSP (lisp_type))
+        cursor_type = mc_lisp_to_cursor_type (XCAR (lisp_type));
+        else
+          cursor_type = mc_lisp_to_cursor_type (lisp_type);
+      if (CONSP (lisp_type))
+        cursor_width = XFIXNUM (XCAR (XCDR (lisp_type)));
+        else
+          cursor_width = 1;
+      foreground = Fnth (make_fixnum (2), specs);
+      if (STRINGP (foreground))
+        foreground = mc_color_vector_calc (w, foreground);
+      struct glyph_matrix *matrix = w->current_matrix;
+      int row_start, row_end, window_row_start, window_row_end;
+      int i;
+      Lisp_Object temp = Qnil;
+      Lisp_Object vspecs = Qnil;
+      for (i = 0; i < matrix->nrows; ++i)
+        {
+          struct glyph_row *row = MATRIX_ROW (matrix, i);
+          row_start = MATRIX_ROW_START_CHARPOS (row);
+          if ((header_line_format > 0 && i == 1)
+               || (header_line_format == 0 && i == 0))
+            window_row_start = row_start;
+          if (!row->enabled_p)
+            {
+              window_row_end = row_end;
+              break;
+            }
+            else
+              {
+                row_end = MATRIX_ROW_END_CHARPOS (row);
+                temp = listn (CONSTYPE_HEAP, 3, make_fixnum (i),
+                                                make_fixnum (row_start),
+                                                make_fixnum (row_end));
+                vspecs = Fcons (temp, vspecs);
+              }
+        }
+      if (posint >= window_row_start
+          && posint <= window_row_end)
+        {
+        Lisp_Object vlist;
+        for (vlist = Fnreverse (vspecs);
+             CONSP (vlist);
+             vlist = XCDR (vlist))
+          {
+            int count = XFIXNUM (Fnth (make_fixnum (0), XCAR (vlist)));
+            int pos_start = XFIXNUM (Fnth (make_fixnum (1), XCAR (vlist)));
+            int pos_end = XFIXNUM (Fnth (make_fixnum (2), XCAR (vlist)));
+            struct glyph_row *row = MATRIX_ROW (w->current_matrix, count);
+            int area;
+            int relative_x = 0;
+            for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+              {
+                struct glyph *glyph = row->glyphs[area];
+                struct glyph *glyph_end = glyph + row->used[area];
+                if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
+                  ++glyph_end;
+                if (mc_stderr_p
+                    && glyph < glyph_end)
+                  fprintf (stderr,
+"\ncount (%d) | window_row_start/end (%d/%d) | row_start/end (%d/%d)\n\
+============================ MULTIPLE CURSORS =================================\n\
+Glyph#/Total Rel.X T       Pos O   W     Code Face LR     X    Y HPOS VPOS ZV C\n",
+count, window_row_start, window_row_end, pos_start, pos_end);
+                for (; glyph < glyph_end; ++glyph)
+                  {
+                    if (((header_line_format > 0 && count > 0)
+                         || header_line_format == 0)
+                        && (glyph->charpos == posint
+                            /* The space appended to a row ending with a new line
+                            does not have a `glyph->charpos` (-1, 0) that we can
+                            use for this particular application.  When there is a
+                            `buffer-display-table' entry that assigns a visible
+                            glyph to a new line, there is no problem because that
+                            glyph has a `glyph->charpos' that we can use.  When
+                            no visible EOL glyph exists, we use the following
+                            test:  the appended space has a position that is one
+                            less than the end of the matrix row. */
+                            || (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                && posint == MATRIX_ROW_END_CHARPOS (row) - 1))
+                        && glyph->y <= window_text_bottom_y (w))
+                      {
+                        current_col = mc_current_column (w, posint);
+                        if (NILP (foreground))
+                          {
+                            /* red */
+                            if (current_col % 2 != 0
+                                && !fill_column_p)
+                              foreground = odd_color_vector;
+                            /* yellow */
+                            if (current_col % 2 == 0
+                                && !fill_column_p)
+                              foreground = even_color_vector;
+                            /* red */
+                            if (current_col % 2 != 0
+                                && fill_column_p
+                                && current_col <= fill_col)
+                              foreground = odd_color_vector;
+                            /* yellow */
+                            if (current_col % 2 == 0
+                                && fill_column_p
+                                && current_col <= fill_col)
+                              foreground = even_color_vector;
+                            /* green */
+                            if (fill_column_p
+                                && current_col > fill_col)
+                              foreground = fill_color_vector;
+                          }
+                        mc_engine (row, glyph, area, relative_x,
+                                   w, posint, cursor_type, cursor_width, foreground, active_p,
+                                   minimal_p, MULTIPLE_CURSORS, &result);
+                        break;
+                      }
+                      else if (mc_stderr_p)
+                        mc_dump_glyph (row, glyph, area, relative_x);
+                    relative_x += glyph->pixel_width;
+                  }
+              }
+          }
+        }
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+/* `w->multiple_cursors_cache' is set for the window, not buffer+window -- i.e., all buffers appearing
+in the same window via `switch-to-buffer' will have `w->multiple_cursors_cache'.  This behavior
+is consistent with functions such as `set-window-display-table'.  We deal with this in
+`nsterm.m' / `w32term.c' / `xterm.c' by comparing `w->contents' to the value of the `buf'
+stored in `w->multiple_cursors_cache'. */
+  if (!NILP (result))
+    wset_multiple_cursors_cache (w, listn (CONSTYPE_HEAP, 3,
+                                 Freverse (result),
+                                 Fcons (window, Qnil),
+                                 Fcons (w->contents, Qnil)));
+  w->mc.draw_multiple_cursors = false;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_draw_multiple_cursors:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_draw_crosshairs (struct window *w, bool active_p, bool minimal_p)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_draw_crosshairs (%s):  active_p (%d) | minimal_p (%d)\n",
+                        window_char, active_p, minimal_p);
+    }
+#endif
+  bool mc_stderr_p = !NILP (BVAR (current_buffer, mc_stderr));
+  ptrdiff_t opoint_pt = (w == XWINDOW (selected_window))
+                        ? PT
+                        : XFIXNUM (Fmarker_position (w->pointm));
+  int opoint_x = w->phys_cursor.x;
+  int opoint_y = w->phys_cursor.y;
+  int opoint_hpos = w->phys_cursor.hpos;
+  int opoint_vpos = w->phys_cursor.vpos;
+  struct glyph *real_phys_cursor_glyph =
+    mc_get_phys_cursor_glyph (w, opoint_x, opoint_hpos, opoint_vpos);
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  /* When swiching to another buffer (e.g., a new buffer), `w->contents` may not
+  necessarily be the `current_buffer`.  In such a case, all calculations would
+  be wrong unless `w->contents` is set as the `current_buffer`.  This avoids
+  errors that are time consuming to debug:  break args_out_of_range */
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+/* eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
+   eassert (charpos == BYTE_TO_CHAR (bytepos));
+   eassert (BUF_BEG_BYTE (b) <= bytepos && bytepos <= BUF_Z_BYTE (b)); */
+  ptrdiff_t charpos = marker_position (w->start);
+  ptrdiff_t bytepos = marker_byte_position (w->start);
+  /* Eli Z.:  If window's start point is invalid, it means the window needs to be
+  redisplayed.  Again, I'm not sure I understand how do you get into this situation
+  in the middle of redisplay. */
+  bool barf_crash_one = (charpos >= BEGV && charpos <= ZV) ? false : true;
+  if (barf_crash_one)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  /* Eli Z.:  Likewise.  Markers are updated when a buffer is modified, so this
+  should never happen. */
+  bool barf_crash_two = (charpos == BYTE_TO_CHAR (bytepos)) ? false : true;
+  if (barf_crash_two)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  /* `matrix_row' in `dispnew.c` contains the following tests,
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows); */
+  bool barf_crash_three = (w->current_matrix && w->current_matrix->rows) ? false : true;
+  if (barf_crash_three)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  bool barf_crash_four = (opoint_vpos >= 0 && opoint_vpos < w->current_matrix->nrows) ? false : true;
+  if (barf_crash_four)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  if (!BUFFERP (buf))
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  if (NILP (BVAR (b, crosshairs)))
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  if (NILP (BVAR (b, crosshairs_horizontal_ruler))
+      && NILP (BVAR (b, crosshairs_vertical_ruler)))
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+/* ******************************************************************************
+                              BEGIN JOURNEY ...
+****************************************************************************** */
+  int frame_char_width = FRAME_COLUMN_WIDTH (f);
+  int text_area_width = window_box_width (w, TEXT_AREA);
+  bool cursor_in_fringe_p = w->output_cursor.x + frame_char_width >= text_area_width;
+  struct glyph_row *glyph_row;
+  int cursor_width = 1;
+  ptrdiff_t posint = -1;
+  ptrdiff_t current_col = mc_current_column (w, opoint_pt);
+  bool fill_column_p = !NILP (BVAR (b, fill_column));
+  int fill_col = XFIXNUM (BVAR (b, fill_column));
+  int fill_column_x = (fill_column_p)
+                      ? fill_col * frame_char_width
+                      : 0;
+  Lisp_Object result = Qnil;
+  int flavor;
+  /* Values for the current column of the vertical line. */
+  Lisp_Object foreground = Fmake_vector (make_fixnum (3), Qnil);
+  enum face_id face_id;
+/* ******************************************************************************
+                             COLOR OF CROSSHAIRS
+****************************************************************************** */
+  enum face_id even_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-numbered-column-face"), true);
+  struct face *even_face = FACE_FROM_ID (f, even_face_id);
+  Lisp_Object even_color = even_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (even_color);
+  Lisp_Object even_color_vector = mc_color_vector_calc (w, even_color);
+  enum face_id odd_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-numbered-column-face"), true);
+  struct face *odd_face = FACE_FROM_ID (f, odd_face_id);
+  Lisp_Object odd_color = odd_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (odd_color);
+  Lisp_Object odd_color_vector = mc_color_vector_calc (w, odd_color);
+  enum face_id fill_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-beyond-fill-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-beyond-fill-column-face"), true);
+  struct face *fill_face = FACE_FROM_ID (f, fill_face_id);
+  Lisp_Object fill_color = fill_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (fill_color);
+  Lisp_Object fill_color_vector = mc_color_vector_calc (w, fill_color);
+  /* red */
+  if (current_col % 2 != 0
+      && !fill_column_p)
+    foreground = odd_color_vector;
+  /* yellow */
+  if (current_col % 2 == 0
+      && !fill_column_p)
+    foreground = even_color_vector;
+  /* red */
+  if (current_col % 2 != 0
+      && fill_column_p
+      && current_col <= fill_col)
+    foreground = odd_color_vector;
+  /* yellow */
+  if (current_col % 2 == 0
+      && fill_column_p
+      && current_col <= fill_col)
+    foreground = even_color_vector;
+  /* green */
+  if (fill_column_p
+      && current_col > fill_col)
+    foreground = fill_color_vector;
+/* ******************************************************************************
+                           ERASE THE REAL CURSOR
+****************************************************************************** */
+/* `w->phys_cursor.x/y/hpos/vpos` are incorrect after evaluating (scroll-left 1)
+a couple of times.  Redisplay erases the real cursor almost immediately after
+`mc_draw_crosshairs' runs its course -- almost too quickly to see it happening.
+The character where Emacs thinks the real cursor is located gets redrawn, albiet
+without the real cursor.  Emacs thinks the real cursor is one character to the
+right of where it should be -- this is most likely due to an incorrect HPOS.
+This phenomena does not occur when (scroll-left 1) is called interactively; e.g.,
+horizontal scroll wheel.  Inasmuch as `erase_phys_cursor' updates more than
+merely the aforementioned coordinates, resetting those coordinates after the fact
+is insufficient to fix the problem.  We use `w->output_cursor.x/y/hpos/vpos`
+because those coordinates are correct.  We fix `w->phys_cursor.x/y/hpos/vpos`
+BEFORE calling `erase_phys_cursor' so that other goodies are updated. */
+  if (w->hscroll > 0)
+    {
+      w->phys_cursor.x = w->output_cursor.x;
+      w->phys_cursor.y = w->output_cursor.y;
+      w->phys_cursor.hpos = w->output_cursor.hpos;
+      w->phys_cursor.vpos = w->output_cursor.vpos;
+    }
+  if (!minimal_p)
+    erase_phys_cursor (w);
+/* ******************************************************************************
+                          REPLACE THE REAL CURSOR
+****************************************************************************** */
+  glyph_row = MATRIX_ROW (w->current_matrix, opoint_vpos);
+  if (!cursor_in_fringe_p)
+    flavor = MC_GLYPH;
+    /* This condition probably does not exist for the real fake cursor. */
+    else if (cursor_in_fringe_p
+             && glyph_row->continued_p)
+      flavor = MC_PILCROW;
+      else if (cursor_in_fringe_p
+               && glyph_row->truncated_on_right_p)
+        flavor = MC_HOLLOW_RECTANGLE_RIGHT_ARROW;
+        else if (cursor_in_fringe_p
+                 && !glyph_row->continued_p
+                 && !glyph_row->truncated_on_right_p)
+          flavor = MC_HOLLOW_RECTANGLE;
+  face_id = (real_phys_cursor_glyph == NULL)
+              ? DEFAULT_FACE_ID
+              : real_phys_cursor_glyph->face_id;
+  int opoint_fx = -1;
+  int opoint_fy = -1;
+  int opoint_h = -1;
+  /* FIXME:  Put in some code to default to HOLLOW_BOX_CURSOR if the user has
+  unwittingly come up with some unacceptable form of unrecognized cursor type. */
+  Lisp_Object cursor_lisp_type = BVAR (b, mc_real_fake_cursor);
+  enum text_cursor_kinds temp_cursor_type = (CONSP (cursor_lisp_type))
+                                             ? mc_lisp_to_cursor_type (XCAR (cursor_lisp_type))
+                                             : mc_lisp_to_cursor_type (cursor_lisp_type);
+  if (flavor == MC_PILCROW
+      || flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW
+      || flavor == MC_HOLLOW_RECTANGLE)
+    temp_cursor_type = RIGHT_FRINGE_BITMAP;
+  int initial_cursor_width = (CONSP (cursor_lisp_type))
+                              ? XFIXNUM (XCAR (XCDR (cursor_lisp_type)))
+                              : 1;
+  enum face_id cursor_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+  struct face *cursor_face = FACE_FROM_ID (f, cursor_face_id);
+  Lisp_Object cursor_color = cursor_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (cursor_color);
+  Lisp_Object cursor_fg = (temp_cursor_type == NO_CURSOR)
+                          ? foreground
+                          : mc_color_vector_calc (w, cursor_color);
+  /* FIXME:  This creates two MC_GLYPH at the same location and needs to be
+  reduced to just one MC_GLYPH, one vertical bar, and one horizontal bar.  The
+  problem with this is that the letter at point gets written twice and will be
+  just a little thicker than as would normally be the case. */
+  bool fill_column_trumps_p = (!NILP (BVAR (b, crosshairs_vertical_ruler))
+                               && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))
+                               && opoint_x == fill_column_x);
+  /* fringe bitmaps use face_id to set the foreground color.  The overlay-arrow
+  is presently the only situation where the `active_p` and `minimal_p` are
+  used to determine the applicable face_id. */
+  Lisp_Object foreground_lsl = (Fmake_vector (make_fixnum (3), Qnil));
+  ASET (foreground_lsl, 0, make_float (-1.0));
+  ASET (foreground_lsl, 1, make_float (-1.0));
+  ASET (foreground_lsl, 2, make_float (-1.0));
+  mc_helper (w, opoint_x, opoint_fx, opoint_y, opoint_fy, opoint_hpos,
+             opoint_vpos, opoint_h, LEFT_FRINGE_BITMAP, initial_cursor_width,
+             foreground_lsl, mc_bg_lsl (w, face_id), active_p, minimal_p,
+             MC_OVERLAY_ARROW_BITMAP, opoint_pt, &result);
+  bool updating_frame_p = false;
+  if (minimal_p)
+    goto crosshairs_finish;
+    else if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  if (temp_cursor_type == NO_CURSOR
+      && !minimal_p)
+    {
+      int _wd;
+      if (flavor == MC_GLYPH)
+        mc_get_phys_cursor_geometry (w, glyph_row, opoint_x, &opoint_fx,
+                                     opoint_y, &opoint_fy, opoint_hpos, opoint_vpos,
+                                     &opoint_h, HBAR_CURSOR, initial_cursor_width, &_wd);
+      mc_helper (w, opoint_x, opoint_fx, opoint_y, opoint_fy, opoint_hpos,
+                 opoint_vpos, opoint_h, HBAR_CURSOR, cursor_width, cursor_fg,
+                 mc_bg_lsl (w, face_id), active_p, minimal_p, flavor,
+                 opoint_pt, &result);
+      if (flavor == MC_GLYPH)
+        mc_get_phys_cursor_geometry (w, glyph_row, opoint_x, &opoint_fx,
+                                     opoint_y, &opoint_fy, opoint_hpos, opoint_vpos,
+                                     &opoint_h, BAR_CURSOR, initial_cursor_width, &_wd);
+      mc_helper (w, opoint_x, opoint_fx, opoint_y, opoint_fy, opoint_hpos,
+                 opoint_vpos, opoint_h, BAR_CURSOR, cursor_width, cursor_fg,
+                 mc_bg_lsl (w, face_id), active_p, minimal_p, flavor,
+                 opoint_pt, &result);
+    }
+    else if (!minimal_p)
+      {
+        int _wd;
+        if (flavor == MC_GLYPH)
+          mc_get_phys_cursor_geometry (w, glyph_row, opoint_x, &opoint_fx,
+                                       opoint_y, &opoint_fy, opoint_hpos, opoint_vpos,
+                                       &opoint_h, temp_cursor_type, initial_cursor_width, &_wd);
+        mc_helper (w, opoint_x, opoint_fx, opoint_y, opoint_fy, opoint_hpos,
+                   opoint_vpos, opoint_h, temp_cursor_type, cursor_width,
+                   cursor_fg, mc_bg_lsl (w, face_id), active_p, minimal_p,
+                   flavor, opoint_pt, &result);
+      }
+  if (NILP (BVAR (b, crosshairs_horizontal_ruler)))
+    goto vertical_ruler;
+    else
+/* ******************************************************************************
+                HORIZONTAL RULER:  FIRST X => EOL
+                                and
+       HORIZONTAL RULER:  DRAW FLOATING GLYPHLESS LINE (EOL TO FRINGE)
+****************************************************************************** */
+    {
+      struct glyph_row *row = MATRIX_ROW (w->current_matrix, opoint_vpos);
+      int area;
+      int relative_x = 0;
+      for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+        {
+          struct glyph *glyph = row->glyphs[area];
+          struct glyph *glyph_end = glyph + row->used[area];
+          /* Glyph for a line end in text.  */
+          if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
+            ++glyph_end;
+          if (mc_stderr_p
+              && glyph < glyph_end)
+            fprintf (stderr,
+"\n============================ HORIZONTAL RULER ==================================\n\
+Glyph#/Total Rel.X T       Pos O   W     Code Face LR     X    Y HPOS VPOS ZV C\n");
+          for (; glyph < glyph_end; ++glyph)
+            {
+              mc_engine (row, glyph, area, relative_x,
+                         w, posint, HBAR_CURSOR, cursor_width, foreground, active_p,
+                         minimal_p, HORIZONTAL_RULER, &result);
+              relative_x += glyph->pixel_width;
+            }
+        }
+    }
+/* ******************************************************************************
+           VERTICAL RULER:  COMBINATION OF GLYPH & GLYPHLESS CURSORS
+****************************************************************************** */
+  vertical_ruler:
+  if (NILP (BVAR (b, crosshairs_vertical_ruler))
+      || fill_column_trumps_p)
+    goto crosshairs_finish;
+    else
+      {
+        int header_line_format = WINDOW_HEADER_LINE_HEIGHT (w);
+        struct glyph_matrix *matrix = w->current_matrix;
+        int row_start, row_end, window_row_start, window_row_end;
+        int i;
+        Lisp_Object temp = Qnil;
+        Lisp_Object vspecs = Qnil;
+        for (i = 0; i < matrix->nrows; ++i)
+          {
+            struct glyph_row *row = MATRIX_ROW (matrix, i);
+            row_start = MATRIX_ROW_START_CHARPOS (row);
+            if ((header_line_format > 0 && i == 1)
+                 || (header_line_format == 0 && i == 0))
+              window_row_start = row_start;
+            if (!row->enabled_p)
+              {
+                window_row_end = row_end;
+                break;
+              }
+              else
+                {
+                  row_end = MATRIX_ROW_END_CHARPOS (row);
+                  temp = listn (CONSTYPE_HEAP, 3, make_fixnum (i),
+                                                  make_fixnum (row_start),
+                                                  make_fixnum (row_end));
+                  vspecs = Fcons (temp, vspecs);
+                }
+          }
+        Lisp_Object vlist;
+        for (vlist = Fnreverse (vspecs);
+             CONSP (vlist);
+             vlist = XCDR (vlist))
+          {
+            int count = XFIXNUM (Fnth (make_fixnum (0), XCAR (vlist)));
+            int pos_start = XFIXNUM (Fnth (make_fixnum (1), XCAR (vlist)));
+            int pos_end = XFIXNUM (Fnth (make_fixnum (2), XCAR (vlist)));
+            struct glyph_row *row = MATRIX_ROW (w->current_matrix, count);
+            int temp_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+            int area;
+            int relative_x = 0;
+            for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+              {
+                struct glyph *glyph = row->glyphs[area];
+                struct glyph *glyph_end = glyph + row->used[area];
+                if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
+                  ++glyph_end;
+                if (mc_stderr_p
+                    && glyph < glyph_end)
+                  fprintf (stderr,
+"\ncount (%d) | window_row_start/end (%d/%d) | row_start/end (%d/%d)\n\
+============================= VERTICAL RULER ==================================\n\
+Glyph#/Total Rel.X T       Pos O   W     Code Face LR     X    Y HPOS VPOS ZV C\n",
+count, window_row_start, window_row_end, pos_start, pos_end);
+                for (; glyph < glyph_end; ++glyph)
+                  {
+                    bool real_fake_cursor_p = (opoint_y == glyph->y
+                                               && opoint_vpos == temp_vpos);
+                    if (((header_line_format > 0 && count > 0)
+                         || header_line_format == 0)
+                        && (relative_x + glyph->pixel_width > opoint_x
+                            || glyph == glyph_end - 1)
+                        && glyph->y <= window_text_bottom_y (w)
+                        && !real_fake_cursor_p)
+                      {
+                        mc_engine (row, glyph, area, relative_x,
+                                   w, posint, BAR_CURSOR, cursor_width, foreground, active_p,
+                                   minimal_p, VERTICAL_RULER, &result);
+                        break;
+                      }
+                      else if (mc_stderr_p)
+                        mc_dump_glyph (row, glyph, area, relative_x);
+                    relative_x += glyph->pixel_width;
+                  }
+              }
+          }
+      }
+/* ******************************************************************************
+                                SET THE CACHE
+****************************************************************************** */
+  crosshairs_finish:
+  if (!minimal_p
+      && updating_frame_p)
+    update_end (XFRAME (w->frame));
+  if (!NILP (result))
+    wset_crosshairs_cache (w, listn (CONSTYPE_HEAP, 3,
+                                     Freverse (result),
+                                     Fcons (window, Qnil),
+                                     Fcons (w->contents, Qnil)));
+  w->mc.draw_crosshairs = false;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_draw_crosshairs:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_draw_fill_column (struct window *w, bool active_p, bool minimal_p)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_draw_fill_column (%s):  active_p (%d) | minimal_p (%d)\n",
+                        window_char, active_p, minimal_p);
+    }
+#endif
+  bool mc_stderr_p = !NILP (BVAR (current_buffer, mc_stderr));
+  int opoint_x = w->phys_cursor.x;
+  int opoint_y = w->phys_cursor.y;
+  int opoint_hpos = w->phys_cursor.hpos;
+  int opoint_vpos = w->phys_cursor.vpos;
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  /* When swiching to another buffer (e.g., a new buffer), `w->contents` may not
+  necessarily be the `current_buffer`.  In such a case, all calculations would
+  be wrong unless `w->contents` is set as the `current_buffer`.  This avoids
+  errors that are time consuming to debug:  break args_out_of_range */
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+/* eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
+   eassert (charpos == BYTE_TO_CHAR (bytepos));
+   eassert (BUF_BEG_BYTE (b) <= bytepos && bytepos <= BUF_Z_BYTE (b)); */
+  ptrdiff_t charpos = marker_position (w->start);
+  ptrdiff_t bytepos = marker_byte_position (w->start);
+  /* Eli Z.:  If window's start point is invalid, it means the window needs to be
+  redisplayed.  Again, I'm not sure I understand how do you get into this situation
+  in the middle of redisplay. */
+  bool barf_crash_one = (charpos >= BEGV && charpos <= ZV) ? false : true;
+  if (barf_crash_one)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  /* Eli Z.:  Likewise.  Markers are updated when a buffer is modified, so this
+  should never happen. */
+  bool barf_crash_two = (charpos == BYTE_TO_CHAR (bytepos)) ? false : true;
+  if (barf_crash_two)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  /* `matrix_row' in `dispnew.c` contains the following tests,
+  eassert (matrix && matrix->rows);
+  eassert (row >= 0 && row < matrix->nrows); */
+  bool barf_crash_three = (w->current_matrix && w->current_matrix->rows) ? false : true;
+  if (barf_crash_three)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  bool barf_crash_four = (opoint_vpos >= 0 && opoint_vpos < w->current_matrix->nrows) ? false : true;
+  if (barf_crash_four)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  if (!BUFFERP (buf))
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+  if (NILP (BVAR (b, mc_fill_column)))
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      return;
+    }
+/* ******************************************************************************
+                              BEGIN JOURNEY ...
+****************************************************************************** */
+  int frame_char_width = FRAME_COLUMN_WIDTH (f);
+  int cursor_width = 1;
+  ptrdiff_t posint = -1;
+  bool fill_column_p = !NILP (BVAR (b, fill_column));
+  int fill_col = XFIXNUM (BVAR (b, fill_column));
+  int fill_column_x = (fill_column_p)
+                      ? fill_col * frame_char_width
+                      : 0;
+  Lisp_Object result = Qnil;
+/* ******************************************************************************
+                             COLOR OF FILL COLUMN
+****************************************************************************** */
+  enum face_id fill_column_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column_inactive_windows))
+     && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+      ? lookup_named_face (w, f, intern ("mc-fill-column-inactive-face"), true)
+    : (!active_p
+       && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, crosshairs_vertical_ruler))
+       && opoint_x == fill_column_x)
+      ? lookup_named_face (w, f, intern ("mc-fill-column-opoint-inactive-face"), true)
+    : (active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, crosshairs_vertical_ruler))
+       && opoint_x == fill_column_x)
+      ? lookup_named_face (w, f, intern ("mc-fill-column-opoint-face"), true)
+    : (!active_p
+       && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, crosshairs_vertical_ruler))
+       && opoint_x != fill_column_x)
+      ? lookup_named_face (w, f, intern ("mc-fill-column-inactive-face"), true)
+    : (active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, crosshairs_vertical_ruler))
+       && opoint_x != fill_column_x)
+      ? lookup_named_face (w, f, intern ("mc-fill-column-face"), true)
+    : lookup_named_face (w, f, intern ("mc-fill-column-face"), true);
+  struct face *fill_column_face = FACE_FROM_ID (f, fill_column_face_id);
+  Lisp_Object fill_column_color = fill_column_face->lface[LFACE_FOREGROUND_INDEX];
+  CHECK_STRING (fill_column_color);
+  Lisp_Object foreground = mc_color_vector_calc (w, fill_column_color);
+  bool updating_frame_p = false;
+  if (minimal_p)
+    goto mc_fill_column_finish;
+    else if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+/* ******************************************************************************
+           FILL COLUMN:  COMBINATION OF GLYPH & GLYPHLESS CURSORS
+****************************************************************************** */
+  int header_line_format = WINDOW_HEADER_LINE_HEIGHT (w);
+  struct glyph_matrix *matrix = w->current_matrix;
+  int row_start, row_end, window_row_start, window_row_end;
+  int i;
+  Lisp_Object temp = Qnil;
+  Lisp_Object vspecs = Qnil;
+  for (i = 0; i < matrix->nrows; ++i)
+    {
+      struct glyph_row *row = MATRIX_ROW (matrix, i);
+      row_start = MATRIX_ROW_START_CHARPOS (row);
+      if ((header_line_format > 0 && i == 1)
+           || (header_line_format == 0 && i == 0))
+        window_row_start = row_start;
+      if (!row->enabled_p)
+        {
+          window_row_end = row_end;
+          break;
+        }
+        else
+          {
+            row_end = MATRIX_ROW_END_CHARPOS (row);
+            temp = listn (CONSTYPE_HEAP, 3, make_fixnum (i),
+                                            make_fixnum (row_start),
+                                            make_fixnum (row_end));
+            vspecs = Fcons (temp, vspecs);
+          }
+    }
+  Lisp_Object vlist;
+  for (vlist = Fnreverse (vspecs);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      int count = XFIXNUM (Fnth (make_fixnum (0), XCAR (vlist)));
+      int pos_start = XFIXNUM (Fnth (make_fixnum (1), XCAR (vlist)));
+      int pos_end = XFIXNUM (Fnth (make_fixnum (2), XCAR (vlist)));
+      struct glyph_row *row = MATRIX_ROW (w->current_matrix, count);
+      int temp_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+      int area;
+      int relative_x = 0;
+      for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+        {
+          struct glyph *glyph = row->glyphs[area];
+          struct glyph *glyph_end = glyph + row->used[area];
+          if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
+            ++glyph_end;
+          if (mc_stderr_p
+              && glyph < glyph_end)
+            fprintf (stderr,
+"\ncount (%d) | window_row_start/end (%d/%d) | row_start/end (%d/%d)\n\
+================================ FILL COLUMN ==================================\n\
+Glyph#/Total Rel.X T       Pos O   W     Code Face LR     X    Y HPOS VPOS ZV C\n",
+count, window_row_start, window_row_end, pos_start, pos_end);
+          for (; glyph < glyph_end; ++glyph)
+            {
+              bool real_fake_cursor_p = (opoint_x == fill_column_x
+                                         && opoint_y == glyph->y
+                                         && opoint_hpos == glyph - row->glyphs[TEXT_AREA]
+                                         && opoint_vpos == temp_vpos);
+              if (((header_line_format > 0 && count > 0)
+                   || header_line_format == 0)
+                  && (relative_x + glyph->pixel_width > fill_column_x
+                      || glyph == glyph_end - 1)
+                  && glyph->y <= window_text_bottom_y (w)
+                  && !real_fake_cursor_p)
+                {
+                  mc_engine (row, glyph, area, relative_x,
+                             w, posint, BAR_CURSOR, cursor_width, foreground, active_p,
+                             minimal_p, FILL_COLUMN, &result);
+                  break;
+                }
+                else if (((header_line_format > 0 && count > 0)
+                          || header_line_format == 0)
+                         && (relative_x + glyph->pixel_width > fill_column_x
+                             || glyph == glyph_end - 1)
+                         && glyph->y <= window_text_bottom_y (w)
+                         && real_fake_cursor_p)
+                  {
+                    if (mc_stderr_p)
+                      {
+                        fprintf (stderr, "\nREAL FAKE CURSOR\n");
+                        mc_dump_glyph (row, glyph, area, relative_x);
+                      }
+                    break;
+                  }
+                  else if (mc_stderr_p)
+                    mc_dump_glyph (row, glyph, area, relative_x);
+              relative_x += glyph->pixel_width;
+            }
+        }
+    }
+/* ******************************************************************************
+                                SET THE CACHE
+****************************************************************************** */
+  mc_fill_column_finish:
+  if (!minimal_p
+      && updating_frame_p)
+    update_end (XFRAME (w->frame));
+  if (!NILP (result))
+    wset_mc_fill_column_cache (w, listn (CONSTYPE_HEAP, 3,
+                                     Freverse (result),
+                                     Fcons (window, Qnil),
+                                     Fcons (w->contents, Qnil)));
+  w->mc.draw_fill_column = false;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_draw_fill_column:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_redraw_multiple_cursors (struct window *w)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_redraw_multiple_cursors (%s)\n", window_char);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  bool minimal_p = false;
+  int flavor;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  for (vlist = XCAR (w->multiple_cursors_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      bool remove_p = false;
+      mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                            cursor_width, foreground, active_p, minimal_p,
+                            MC_GLYPH, posint, remove_p);
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_redraw_multiple_cursors:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_redraw_crosshairs (struct window *w)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_redraw_crosshairs (%s)\n", window_char);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  bool minimal_p = false;
+  int flavor;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  for (vlist = XCAR (w->crosshairs_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      bool remove_p = false;
+      mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                            cursor_width, foreground, active_p, minimal_p,
+                            flavor, posint, remove_p);
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_redraw_crosshairs:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_redraw_fill_column (struct window *w)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_redraw_fill_column (%s)\n", window_char);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  bool minimal_p = false;
+  int flavor;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  for (vlist = XCAR (w->mc_fill_column_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      bool remove_p = false;
+      mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                            cursor_width, foreground, active_p, minimal_p,
+                            flavor, posint, remove_p);
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_redraw_fill_column:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_erase_multiple_cursors (struct window *w, bool delete_cache)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_erase_multiple_cursors (%s):  delete_cache (%d)\n", window_char, delete_cache);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  bool minimal_p = false;
+  int flavor = NO_FLAVOR;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  mc_erase_glyph_cursors (w, w->phys_cursor.x, w->phys_cursor.y, w->phys_cursor.hpos,
+                          w->phys_cursor.vpos, w->phys_cursor_type, w->phys_cursor_width,
+                          flavor);
+  for (vlist = XCAR (w->multiple_cursors_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      if (flavor == MC_GLYPH)
+        mc_erase_glyph_cursors (w, x, y, hpos, vpos, cursor_type, cursor_width, flavor);
+        else
+          {
+            bool remove_p = true;
+            mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                                  cursor_width, background, active_p,
+                                  minimal_p, flavor, posint, remove_p);
+          }
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+  if (delete_cache)
+    wset_multiple_cursors_cache (w, Qnil);
+  w->mc.erase_multiple_cursors = false;
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_erase_multiple_cursors:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_erase_crosshairs (struct window *w, bool delete_cache, bool minimal_p)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_erase_crosshairs (%s):  delete_cache (%d)\n",
+                       window_char, delete_cache);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  int flavor = NO_FLAVOR;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  if (!minimal_p)
+    mc_erase_glyph_cursors (w, w->phys_cursor.x, w->phys_cursor.y, w->phys_cursor.hpos,
+                            w->phys_cursor.vpos, w->phys_cursor_type, w->phys_cursor_width,
+                            flavor);
+  for (vlist = XCAR (w->crosshairs_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      if (flavor == MC_GLYPH)
+        mc_erase_glyph_cursors (w, x, y, hpos, vpos, cursor_type, cursor_width, flavor);
+        else
+          {
+            bool remove_p = true;
+            mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                                  cursor_width, background, active_p,
+                                  minimal_p, flavor, posint, remove_p);
+          }
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+  if (delete_cache)
+    wset_crosshairs_cache (w, Qnil);
+  w->mc.erase_crosshairs = false;
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_erase_crosshairs:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_erase_fill_column (struct window *w, bool delete_cache)
+{
+/*
+#ifdef GLYPH_DEBUG
+  clock_t start, end;
+  double cpu_time_used;
+  char buf_time[DBL_BUFSIZE_BOUND];
+  start = clock();
+#endif
+*/
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_erase_fill_column (%s):  delete_cache (%d)\n",
+                       window_char, delete_cache);
+    }
+#endif
+  Lisp_Object vlist = Qnil;
+  Lisp_Object fifteen_elements = Qnil;
+  int x, fx, y, fy, hpos, vpos, h;
+  enum text_cursor_kinds cursor_type;
+  int cursor_width;
+  Lisp_Object foreground = Qnil;
+  Lisp_Object background = Qnil;
+  bool active_p = false;
+  bool minimal_p = false;
+  int flavor = NO_FLAVOR;
+  ptrdiff_t posint;
+  bool updating_frame_p = false;
+  if (XFRAME (w->frame) != XFRAME (w->frame)->mc_updating_frame)
+    {
+      updating_frame_p = true;
+      update_begin (XFRAME (w->frame));
+    }
+  for (vlist = XCAR (w->mc_fill_column_cache);
+       CONSP (vlist);
+       vlist = XCDR (vlist))
+    {
+      fifteen_elements = XCAR (vlist);
+      x = XFIXNUM (Fnth (make_fixnum (0), fifteen_elements));
+      fx = XFIXNUM (Fnth (make_fixnum (1), fifteen_elements));
+      y = XFIXNUM (Fnth (make_fixnum (2), fifteen_elements));
+      fy = XFIXNUM (Fnth (make_fixnum (3), fifteen_elements));
+      hpos = XFIXNUM (Fnth (make_fixnum (4), fifteen_elements));
+      vpos = XFIXNUM (Fnth (make_fixnum (5), fifteen_elements));
+      h = XFIXNUM (Fnth (make_fixnum (6), fifteen_elements));
+      cursor_type = mc_lisp_to_cursor_type (Fnth (make_fixnum (7), fifteen_elements));
+      cursor_width = XFIXNUM (Fnth (make_fixnum (8), fifteen_elements));
+      foreground = Fnth (make_fixnum (9), fifteen_elements);
+      background = Fnth (make_fixnum (10), fifteen_elements);
+      active_p = XFIXNUM (Fnth (make_fixnum (11), fifteen_elements));
+      minimal_p = XFIXNUM (Fnth (make_fixnum (12), fifteen_elements));
+      flavor = XFIXNUM (Fnth (make_fixnum (13), fifteen_elements));
+      posint = XFIXNUM (Fnth (make_fixnum (14), fifteen_elements));
+      if (flavor == MC_GLYPH)
+        mc_erase_glyph_cursors (w, x, y, hpos, vpos, cursor_type, cursor_width, flavor);
+        else
+          {
+            bool remove_p = true;
+            mc_draw_erase_hybrid (w, x, fx, y, fy, hpos, vpos, h, cursor_type,
+                                  cursor_width, background, active_p,
+                                  minimal_p, flavor, posint, remove_p);
+          }
+    }
+  if (updating_frame_p)
+    update_end (XFRAME (w->frame));
+  if (delete_cache)
+    wset_mc_fill_column_cache (w, Qnil);
+  w->mc.erase_fill_column = false;
+/*
+#ifdef GLYPH_DEBUG
+  end = clock();
+  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+  dtoastr (buf_time, sizeof buf_time, 0, 0, cpu_time_used);
+  debug_method_add (w, "mc_erase_fill_column:  TIME (%s)", buf_time);
+#endif
+*/
+}
+
+void
+mc_remove_multiple_cursors (struct window *w)
+{
+  bool delete_cache = (w->mc.redisplay_preserve_echo_area == 8
+                       || mc_redisplay == 3)
+                      ? false
+                      : true;
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_remove_multiple_cursors (%s):  delete_cache (%d)\n",
+                        window_char, delete_cache);
+    }
+#endif
+  /* Remove fake cursors.  If we rely upon `update_frame' to remove fake cursors,
+  then it would be too late to remove fake cursors from all areas of the visible
+  window when cutting/pasting text and perhaps a few other situations. */
+  if (!w->pseudo_window_p
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->multiple_cursors_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->multiple_cursors_cache))))
+    mc_erase_multiple_cursors (w, delete_cache);
+}
+
+void
+mc_remove_crosshairs (struct window *w)
+{
+  bool delete_cache = ((w->mc.redisplay_preserve_echo_area == 8
+                        || mc_redisplay == 3)
+                       && !w->mc.draw_crosshairs
+                       && !w->mc.erase_crosshairs)
+                      ? false
+                      : true;
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_remove_crosshairs (%s):  delete_cache (%d)\n",
+                        window_char, delete_cache);
+    }
+#endif
+  /* Remove fake cursors.  If we rely upon `update_frame' to remove fake cursors,
+  then it would be too late to remove fake cursors from all areas of the visible
+  window when cutting/pasting text and perhaps a few other situations. */
+  if (!w->pseudo_window_p
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->crosshairs_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->crosshairs_cache))))
+    {
+      bool minimal_p = false;
+      mc_erase_crosshairs (w, delete_cache, minimal_p);
+    }
+}
+
+void
+mc_remove_fill_column (struct window *w)
+{
+  bool delete_cache = ((w->mc.redisplay_preserve_echo_area == 8
+                        || mc_redisplay == 3)
+                       && !w->mc.draw_fill_column
+                       && !w->mc.erase_fill_column)
+                      ? false
+                      : true;
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_remove_fill_column (%s):  delete_cache (%d)\n",
+                        window_char, delete_cache);
+    }
+#endif
+  /* Remove fake cursors.  If we rely upon `update_frame' to remove fake cursors,
+  then it would be too late to remove fake cursors from all areas of the visible
+  window when cutting/pasting text and perhaps a few other situations. */
+  if (!w->pseudo_window_p
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->mc_fill_column_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->mc_fill_column_cache))))
+    mc_erase_fill_column (w, delete_cache);
+}
+
+void
+mc_multiple_cursors_portal (struct window *w, bool on, bool active_p)
+{
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_multiple_cursors_portal (%s):  on (%d) | active_p (%d)\n",
+                        window_char, on, active_p);
+    }
+#endif
+  bool minimal_p = (!w->mc.draw_multiple_cursors
+                    && mc_redisplay_preserve_echo_area != 8
+                    && mc_redisplay != 3
+                    && w == XWINDOW (selected_window)
+                    && NILP (BVAR (XBUFFER (w->contents), multiple_cursors_draw_forthwith)));
+  if (w->mc.erase_multiple_cursors && w->mc.draw_multiple_cursors
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->multiple_cursors_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->multiple_cursors_cache))))
+    mc_erase_multiple_cursors (w, true);
+  /* `w->multiple_cursors_cache` belongs to the window, not the buffer.  Switching
+  buffers within the same window renders the cache useless. */
+  if (!MINI_WINDOW_P (w)
+      && !NILP (w->multiple_cursors_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+      && !EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->multiple_cursors_cache))))
+    {
+      wset_multiple_cursors_cache (w, Qnil);
+      w->mc.erase_multiple_cursors = false;
+    }
+  if (on
+      && !MINI_WINDOW_P (w)
+      && (w == XWINDOW (selected_window)
+          || !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_inactive_windows)))
+      && NILP (w->multiple_cursors_cache)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    mc_draw_multiple_cursors (w, active_p, minimal_p);
+    else if (on
+             && !MINI_WINDOW_P (w)
+             && !NILP (w->multiple_cursors_cache)
+             && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf))
+             && WINDOWP (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+             && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->multiple_cursors_cache)))
+             && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->multiple_cursors_cache))))
+      {
+        mc_erase_multiple_cursors (w, false);
+        mc_redraw_multiple_cursors (w);
+      }
+}
+
+void
+mc_crosshairs_portal (struct window *w, bool on, bool active_p)
+{
+  /* Remove crosshairs and delete the cache, but ONLY if we plan on redrawing them.
+  In a timer situation, we want to erase and redraw -- we go from `checkpoint_2'
+  in `redisplay_internal' and force our way over to `update_frame' 2 of 3.
+  Emacs refreshes the selected window after about 1 to 2 minutes of no activity
+  even though there is nothing attached to the `time_list'/`idle_timer_list'.
+  In that refresh no-timer situation, we want to erase/draw using the cache. */
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_crosshairs_portal (%s):  on (%d) | active_p (%d)\n",
+                        window_char, on, active_p);
+    }
+#endif
+  bool minimal_p = (!w->mc.draw_crosshairs
+                    && mc_redisplay_preserve_echo_area != 8
+                    && mc_redisplay != 3
+                    && w == XWINDOW (selected_window)
+                    && NILP (BVAR (XBUFFER (w->contents), crosshairs_draw_forthwith)));
+  if (w->mc.erase_crosshairs && w->mc.draw_crosshairs
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->crosshairs_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->crosshairs_cache))))
+    mc_erase_crosshairs (w, true, minimal_p);
+  /* `w->crosshairs_cache` belongs to the window, not the buffer.  Switching
+  buffers within the same window renders the cache useless. */
+  if (!MINI_WINDOW_P (w)
+      && !NILP (w->crosshairs_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+      && !EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->crosshairs_cache))))
+    {
+      wset_crosshairs_cache (w, Qnil);
+      w->mc.erase_crosshairs = false;
+    }
+  if (on
+      && !MINI_WINDOW_P (w)
+      && (w == XWINDOW (selected_window)
+          || !NILP (BVAR (XBUFFER (w->contents), crosshairs_inactive_windows)))
+      && NILP (w->crosshairs_cache)
+      && (!NILP (BVAR (XBUFFER (w->contents), crosshairs))))
+    mc_draw_crosshairs (w, active_p, minimal_p);
+    else if (on
+             && !MINI_WINDOW_P (w)
+             && !NILP (w->crosshairs_cache)
+             && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+             && WINDOWP (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+             && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->crosshairs_cache)))
+             && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->crosshairs_cache))))
+      {
+        mc_erase_crosshairs (w, false, minimal_p);
+        mc_redraw_crosshairs (w);
+      }
+}
+
+void
+mc_fill_column_portal (struct window *w, bool on, bool active_p)
+{
+  /* Remove mc_fill_column and delete the cache, but ONLY if we plan on redrawing them.
+  In a timer situation, we want to erase and redraw -- we go from `checkpoint_2'
+  in `redisplay_internal' and force our way over to `update_frame' 2 of 3.
+  Emacs refreshes the selected window after about 1 to 2 minutes of no activity
+  even though there is nothing attached to the `time_list'/`idle_timer_list'.
+  In that refresh no-timer situation, we want to erase/draw using the cache. */
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window;
+      XSETWINDOW (window, w);
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc_fill_column_portal (%s):  on (%d) | active_p (%d)\n",
+                        window_char, on, active_p);
+    }
+#endif
+  bool minimal_p = (!w->mc.draw_fill_column
+                    && mc_redisplay_preserve_echo_area != 8
+                    && mc_redisplay != 3
+                    && w == XWINDOW (selected_window)
+                    && NILP (BVAR (XBUFFER (w->contents), mc_fill_column_draw_forthwith)));
+  if (w->mc.erase_fill_column && w->mc.draw_fill_column
+      && !MINI_WINDOW_P (w)
+      && !NILP (w->mc_fill_column_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->mc_fill_column_cache))))
+    mc_erase_fill_column (w, true);
+  /* `w->mc_fill_column_cache` belongs to the window, not the buffer.  Switching
+  buffers within the same window renders the cache useless. */
+  if (!MINI_WINDOW_P (w)
+      && !NILP (w->mc_fill_column_cache)
+      && WINDOWP (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+      && !EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->mc_fill_column_cache))))
+    {
+      wset_mc_fill_column_cache (w, Qnil);
+      w->mc.erase_fill_column = false;
+    }
+  if (on
+      && !MINI_WINDOW_P (w)
+      && (w == XWINDOW (selected_window)
+          || !NILP (BVAR (XBUFFER (w->contents), mc_fill_column_inactive_windows)))
+      && NILP (w->mc_fill_column_cache)
+      && (!NILP (BVAR (XBUFFER (w->contents), mc_fill_column))))
+    mc_draw_fill_column (w, active_p, minimal_p);
+    else if (on
+             && !MINI_WINDOW_P (w)
+             && !NILP (w->mc_fill_column_cache)
+             && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column))
+             && WINDOWP (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+             && w == XWINDOW (XCAR (Fnth (make_fixnum (1), w->mc_fill_column_cache)))
+             && EQ (w->contents, XCAR (Fnth (make_fixnum (2), w->mc_fill_column_cache))))
+      {
+        mc_erase_fill_column (w, false);
+        mc_redraw_fill_column (w);
+      }
+}
+
+DEFUN ("mc-activate-multiple-cursors", Fmc_activate_multiple_cursors, Smc_activate_multiple_cursors, 1, 1, 0,
+       doc: /* When using a timer, `mc_switches_multiple_cursors' in `keyboard.c' is not called.
+There are also some other circumstances where `mc-activate-multiple-cursors' is helpful. */)
+  (Lisp_Object window)
+{
+  struct window *w = decode_live_window (window);
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), multiple_cursors_conf)))
+    {
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc-activate-multiple-cursors (%s)\n", window_char);
+    }
+#endif
+  w->mc.draw_multiple_cursors = true;
+  w->mc.erase_multiple_cursors = true;
+  return Qnil;
+}
+
+DEFUN ("mc-activate-crosshairs", Fmc_activate_crosshairs, Smc_activate_crosshairs, 1, 1, 0,
+       doc: /* Doc-string. */)
+  (Lisp_Object window)
+{
+  struct window *w = decode_live_window (window);
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    {
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc-activate-crosshairs (%s)\n", window_char);
+    }
+#endif
+  w->mc.draw_crosshairs = true;
+  w->mc.erase_crosshairs = true;
+  w->must_be_updated_p = true;
+  return Qnil;
+}
+
+DEFUN ("mc-activate-fill-column", Fmc_activate_fill_column, Smc_activate_fill_column, 1, 1, 0,
+       doc: /* Doc-string. */)
+  (Lisp_Object window)
+{
+  struct window *w = decode_live_window (window);
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p
+      && BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), mc_fill_column)))
+    {
+      Lisp_Object window_string = Fprin1_to_string (window, Qnil);
+      char *window_char = SSDATA (window_string);
+      fprintf (stderr, "mc-activate-mc-fill-column (%s)\n", window_char);
+    }
+#endif
+  w->mc.draw_fill_column = true;
+  w->mc.erase_fill_column = true;
+  w->must_be_updated_p = true;
+  return Qnil;
+}
+
+DEFUN ("mc-stderr", Fmc_stderr, Smc_stderr, 0, 1, "P",
+       doc: /* Toggle tracing of multiple fake cursors.
+With ARG, turn tracing on if and only if ARG is positive. */)
+  (Lisp_Object arg)
+{
+  struct buffer *b = current_buffer;
+  bool mc_stderr_p = (!NILP (BVAR (current_buffer, mc_stderr)))
+                   ? true
+                   : false;
+  if (NILP (arg))
+    mc_stderr_p = !mc_stderr_p;
+  else
+    {
+      arg = Fprefix_numeric_value (arg);
+      mc_stderr_p = XFIXNUM (arg) > 0;
+    }
+  if (mc_stderr_p)
+    bset_blv_mc_stderr (b, Qt);
+    else
+      bset_blv_mc_stderr (b, Qnil);
+  return Qnil;
+}
+
+/*  (fundamental-mode)
+    (setq display-line-numbers t)
+    (setq buffer-display-table (make-display-table))
+    (aset buffer-display-table
+          ?\t
+          (vector (make-glyph-code ?\u00BB 'font-lock-warning-face)
+                  (make-glyph-code ?\t 'highlight)))
+    (aset buffer-display-table
+          ?\n
+          (vector (make-glyph-code ?\u00B6 'font-lock-comment-face)
+                  ?\n))
+    (setq tab-width 8)
+    (setq-local auto-hscroll-mode 'current-line) */
+
+DEFUN ("mc-debug", Fmc_debug, Smc_debug, 0, 0, "",
+       doc: /* This function used for debugging. */)
+  (void)
+{
+/* ******************************************************************************
+                      PRELIMINARY STUFF
+****************************************************************************** */
+  struct window *w = decode_live_window (selected_window);
+  struct it it;
+  void *itdata = bidi_shelve_cache ();
+  struct it it2;
+  void *it2data = NULL;
+  struct it it3;
+  void *it3data = NULL;
+  enum move_it_result rc = MOVE_X_REACHED;
+  struct text_pos start_text_position;
+  int count = 0;
+  int new_x = 0;
+  int previous_it_c = 0;
+  int previous_it_fetchbyte = 0;
+  int previous_it_current_x = 0;
+  int previous_it_charpos = 0;
+  int previous_it_pixel_width = 0;
+  bool final_loop_p = false;
+  int text_area_width = window_box_width (w, TEXT_AREA);
+/* ******************************************************************************
+                      START DISPLAY -- w->start
+****************************************************************************** */
+  /* Begin the journey at w->start. */
+  SET_TEXT_POS_FROM_MARKER (start_text_position, w->start);
+  start_display (&it, w, start_text_position);
+/* ******************************************************************************
+                GO TO THE BEGINNING OF THE CURRENT LINE.
+****************************************************************************** */
+  /* Place the IT on the current line containing PT. */
+  int voffset = (WINDOW_HEADER_LINE_HEIGHT (w) > 0
+                 && w->output_cursor.vpos > 0)
+                  ? w->output_cursor.vpos - 1
+                  : w->output_cursor.vpos;
+  if (voffset > 0)
+    move_it_by_lines (&it, voffset);
+/* ******************************************************************************
+                       MOVE IT:  INCREMENT == 1 pixel
+****************************************************************************** */
+  fprintf (stderr, "\nit.first_visible_x (%d)\n", it.first_visible_x);
+  while (!final_loop_p)
+    {
+      mc_debug_p = true;
+      final_loop_p = (IT_CHARPOS (it) == ZV)
+                       ? true
+                     : (FETCH_BYTE (IT_BYTEPOS (it)) == '\n'
+                        && it.c != 0)
+                       ? true
+                     : (rc == MOVE_LINE_CONTINUED)
+                       ? true
+                     : (rc == MOVE_LINE_TRUNCATED
+                        && it.current_x - it.first_visible_x > text_area_width)
+                       ? true
+                     : false;
+      if (it.current_x > previous_it_current_x
+          || IT_CHARPOS (it) > previous_it_charpos
+          || it.c != previous_it_c
+          || it.c == 0
+          || it.c == 10)
+        {
+          Lisp_Object character = Fchar_to_string (make_fixnum (it.c));
+          int charpos = IT_CHARPOS (it);
+          fprintf (stderr, "\ncharpos (%d/%d/%d) | first_x (%d) | previous_x (%d) | x (%d) | c (%s) | pw (%d) | hpos (%d)\n",
+                           charpos, previous_it_charpos, FETCH_BYTE (IT_BYTEPOS (it)),
+                           it.first_visible_x,
+                           previous_it_current_x,
+                           it.current_x,
+                           ((!NILP (character)
+                             && it.c == 9)
+                               ? "\\t"
+                             : (!NILP (character)
+                                && it.c == 10)
+                               ? "\\n"
+                             : (!NILP (character)
+                                && it.c != 9
+                                && it.c != 10)
+                               ? SSDATA (character)
+                             : "?"),
+                           it.pixel_width,
+                           it.hpos);
+          previous_it_c = it.c;
+          previous_it_current_x = it.current_x;
+          previous_it_charpos = IT_CHARPOS (it);
+          previous_it_fetchbyte = FETCH_BYTE (IT_BYTEPOS (it));
+          previous_it_pixel_width = it.pixel_width;
+          count += 1;
+        }
+      new_x += 1;
+      SAVE_IT (it2, it, it2data);
+      rc = move_it_in_display_line_to (&it, ZV, new_x, MOVE_TO_POS | MOVE_TO_X);
+      SAVE_IT (it3, it, it3data);
+    }
+/* ******************************************************************************
+                                 THE END
+****************************************************************************** */
+  mc_debug_p = false;
+  bidi_unshelve_cache (itdata, false);
+  return Qnil;
+}
+
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
+
+
 
 /***********************************************************************
 		      Window display dimensions
@@ -11214,7 +16317,18 @@ resize_echo_area_exactly (void)
 	{
 	  windows_or_buffers_changed = 42;
 	  update_mode_lines = 30;
-	  redisplay_internal ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      mc_redisplay_internal = 1;
+      redisplay_internal (1);
+      mc_redisplay_internal = 0;
+
+/* *************************************************************************** */
+
+
 	}
     }
 }
@@ -11701,7 +16815,18 @@ echo_area_display (bool update_frame_p)
 	      ptrdiff_t count = SPECPDL_INDEX ();
 	      specbind (Qredisplay_dont_pause, Qt);
 	      fset_redisplay (f);
-	      redisplay_internal ();
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+          mc_redisplay_internal = 2;
+          redisplay_internal (2);
+          mc_redisplay_internal = 0;
+
+/* *************************************************************************** */
+
+
 	      unbind_to (count, Qnil);
 	    }
 	  else if (FRAME_WINDOW_P (f) && n == 0)
@@ -13380,6 +18505,19 @@ hscroll_window_tree (Lisp_Object window)
 	      else
 		pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  struct display_pos *pos = &cursor_row->start;
+  ptrdiff_t charpos = CHARPOS (pos->pos);
+  bool barf_crash = (charpos < 0 || (charpos >= BUF_BEG (current_buffer) && charpos <= ZV)) ? false : true;
+  if (barf_crash)
+    return hscrolled_p;
+
+/* *************************************************************************** */
+
+
 	      /* Move iterator to pt starting at cursor_row->start in
 		 a line with infinite width.  */
 	      init_to_row_start (&it, w, cursor_row);
@@ -13620,12 +18758,26 @@ text_outside_line_unchanged_p (struct window *w,
    is no longer requested, we clear the echo area or bring back the
    mini-buffer if that is in use.  */
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
 void
-redisplay (void)
+redisplay (int from_where)
 {
-  redisplay_internal ();
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p)
+    fprintf (stderr, "\nredisplay (%d)\n", from_where);
+#endif
+  mc_redisplay = from_where;
+  mc_redisplay_internal = 3;
+  redisplay_internal (3);
+  mc_redisplay_internal = 0;
+  mc_redisplay = 0;
 }
 
+/* *************************************************************************** */
+
 
 static Lisp_Object
 overlay_arrow_string_or_property (Lisp_Object var)
@@ -13891,9 +19043,21 @@ do { if (polling_stopped_here) start_polling ();	\
 /* Perhaps in the future avoid recentering windows if it
    is not necessary; currently that causes some problems.  */
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
 static void
-redisplay_internal (void)
+redisplay_internal (int from_where)
 {
+#ifdef GLYPH_DEBUG
+  if (trace_redisplay_p)
+    fprintf (stderr, "\nredisplay_internal (%d)\n", from_where);
+#endif
+
+/* *************************************************************************** */
+
+
   struct window *w = XWINDOW (selected_window);
   struct window *sw;
   struct frame *fr;
@@ -14295,6 +19459,26 @@ redisplay_internal (void)
 #ifdef HAVE_WINDOW_SYSTEM
 	      update_window_fringes (w, false);
 #endif
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* NOTE:  An idle-timer function may not necessarily trigger `redisplay_window'.
+   `w->must_be_updated_p' is set to true within `mc-activate-crosshairs'.
+-  `optimization 1` (e.g., left/right cursor movement on the first screen line).
+-  `optimization 3` (e.g., left/right cursor movement on screen lines subsequent
+    to the first screen line), bypass `redisplay_window'. */
+
+  block_input ();
+  mc_remove_multiple_cursors (w);
+  mc_remove_crosshairs (w);
+  mc_remove_fill_column (w);
+  unblock_input ();
+
+/* *************************************************************************** */
+
+
 	      goto update;
 	    }
 	  else
@@ -14317,6 +19501,22 @@ redisplay_internal (void)
 		  && (w = XWINDOW (selected_window)) != sw)
 		goto retry;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* NOTE:  An idle-timer function may not necessarily trigger `redisplay_window'.
+   `w->must_be_updated_p' is set to true within `mc-activate-crosshairs'.
+-  `optimization 1` (e.g., left/right cursor movement on the first screen line).
+-  `optimization 3` (e.g., left/right cursor movement on screen lines subsequent
+    to the first screen line), bypass `redisplay_window'. */
+
+    if (w->must_be_updated_p)
+      goto update;
+
+/* *************************************************************************** */
+
+
 	      /* We used to always goto end_of_redisplay here, but this
 		 isn't enough if we have a blinking cursor.  */
 	      if (w->cursor_off_p == w->last_cursor_off_p)
@@ -14358,6 +19558,26 @@ redisplay_internal (void)
 		  *w->desired_matrix->method = 0;
 		  debug_method_add (w, "optimization 3");
 #endif
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* NOTE:  An idle-timer function may not necessarily trigger `redisplay_window'.
+   `w->must_be_updated_p' is set to true within `mc-activate-crosshairs'.
+-  `optimization 1` (e.g., left/right cursor movement on the first screen line).
+-  `optimization 3` (e.g., left/right cursor movement on screen lines subsequent
+    to the first screen line), bypass `redisplay_window'. */
+
+  block_input ();
+  mc_remove_multiple_cursors (w);
+  mc_remove_crosshairs (w);
+  mc_remove_fill_column (w);
+  unblock_input ();
+
+/* *************************************************************************** */
+
+
 		  goto update;
 		}
 	      else
@@ -14738,16 +19958,36 @@ redisplay_preserve_echo_area (int from_where)
   block_buffer_flips ();
   unblock_input ();
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  struct window *w = decode_live_window (selected_window);
+  w->mc.redisplay_preserve_echo_area = from_where;
+  mc_redisplay_preserve_echo_area = from_where;
+
   if (!NILP (echo_area_buffer[1]))
     {
       /* We have a previously displayed message, but no current
 	 message.  Redisplay the previous message.  */
       display_last_displayed_message_p = true;
-      redisplay_internal ();
+      mc_redisplay_internal = 4;
+      redisplay_internal (4);
+      mc_redisplay_internal = 0;
       display_last_displayed_message_p = false;
     }
   else
-    redisplay_internal ();
+    {
+      mc_redisplay_internal = 5;
+      redisplay_internal (5);
+      mc_redisplay_internal = 0;
+    }
+
+  w->mc.redisplay_preserve_echo_area = 0;
+  mc_redisplay_preserve_echo_area = 0;
+
+/* *************************************************************************** */
+
 
   flush_frame (SELECTED_FRAME ());
   unbind_to (count, Qnil);
@@ -17302,6 +22542,25 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   debug_method_add (w, "recenter");
 #endif
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* NOTE:  An idle-timer function may not necessarily trigger `redisplay_window'.
+   `w->must_be_updated_p' is set to true within `mc-activate-crosshairs'.
+-  `optimization 1` (e.g., left/right cursor movement on the first screen line).
+-  `optimization 3` (e.g., left/right cursor movement on screen lines subsequent
+    to the first screen line), bypass `redisplay_window'. */
+
+  block_input ();
+  mc_remove_multiple_cursors (w);
+  mc_remove_crosshairs (w);
+  mc_remove_fill_column (w);
+  unblock_input ();
+
+/* *************************************************************************** */
+
+
   /* Forget any previously recorded base line for line number display.  */
   if (!buffer_unchanged_p)
     w->base_line_number = 0;
@@ -17732,6 +22991,25 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
   else
     TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* NOTE:  An idle-timer function may not necessarily trigger `redisplay_window'.
+   `w->must_be_updated_p' is set to true within `mc-activate-crosshairs'.
+-  `optimization 1` (e.g., left/right cursor movement on the first screen line).
+-  `optimization 3` (e.g., left/right cursor movement on screen lines subsequent
+    to the first screen line), bypass `redisplay_window'. */
+
+  block_input ();
+  mc_remove_multiple_cursors (w);
+  mc_remove_crosshairs (w);
+  mc_remove_fill_column (w);
+  unblock_input ();
+
+/* *************************************************************************** */
+
+
   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*.  */
@@ -20122,6 +25400,17 @@ append_space_for_newline (struct it *it, bool default_face_p)
 	  memset (&it->position, 0, sizeof it->position);
 	  it->object = Qnil;
 	  it->c = it->char_to_display = ' ';
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      if (IT_BYTEPOS (*it) >= ZV_BYTE)
+        it->zv_p = true;
+
+/* *************************************************************************** */
+
+
 	  it->len = 1;
 
 	  /* If the default face was remapped, be sure to use the
@@ -21085,6 +26374,21 @@ display_count_lines_visually (struct it *it)
 static void
 maybe_produce_line_number (struct it *it)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  bool barf_crash = (it->glyph_row == NULL
+                     || it->glyph_row->used[TEXT_AREA] == 0)
+                    ? false
+                    : true;
+  if (barf_crash)
+    return;
+
+/* *************************************************************************** */
+
+
   ptrdiff_t last_line = it->lnum;
   ptrdiff_t start_from, bytepos;
   ptrdiff_t this_line;
@@ -21255,9 +26559,22 @@ maybe_produce_line_number (struct it *it)
       else
 	tem_it.c = tem_it.char_to_display = *p;
       tem_it.len = 1;
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      if (beyond_zv)
+        tem_it.zv_p = true;
+      tem_it.current_y = it->current_y;
+      tem_it.vpos = it->vpos;
       /* Make sure these glyphs will have a "position" of -1.  */
       SET_TEXT_POS (tem_it.position, -1, -1);
       PRODUCE_GLYPHS (&tem_it);
+      tem_it.hpos += 1;
+
+/* *************************************************************************** */
+
 
       /* Stop producing glyphs, and refrain from producing the line
 	 number, if we don't have enough space on this line.  */
@@ -26841,7 +32158,68 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
 	 prepended must be drawn because the first glyph string
 	 draws over it.  */
       i = left_overwritten (head);
-      if (i >= 0)
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      bool skip_p = false;
+      int beg = i;
+
+      if (i >= 0
+          && hl == DRAW_CURSOR
+          && (w->mc.glyph_flavor == MC_GLYPH
+              || w->mc.glyph_flavor == MC_GLYPHLESS
+              || w->mc.glyph_flavor == MC_GLYPH_TAB))
+        while (beg < start)
+          {
+            struct glyph *glyph = (row)->glyphs[area] + beg;
+            switch (glyph->type)
+            {
+              case CHAR_GLYPH:
+                break;
+              case COMPOSITE_GLYPH:
+                break;
+              case STRETCH_GLYPH:
+                {
+                  Lisp_Object character = (CHARACTERP (make_fixnum (glyph->u.ch)))
+                                           ? Fchar_to_string (make_fixnum (glyph->u.ch))
+                                           : Qnil;
+                  fprintf (stderr, "\ncharacter (%d | %s)\n",
+                                   glyph->u.ch,
+                                   ((!NILP (character)
+                                     && glyph->u.ch == 1048596)
+                                       ? "\\T"
+                                     : (!NILP (character)
+                                        && glyph->u.ch == 10)
+                                       ? "\\t"
+                                     : (!NILP (character)
+                                        && glyph->u.ch == 10)
+                                       ? "\\n"
+                                     : (!NILP (character)
+                                        && glyph->u.ch == 32)
+                                       ? "\\s"
+                                     : (!NILP (character)
+                                        && glyph->u.ch != 9
+                                        && glyph->u.ch != 10
+                                        && glyph->u.ch != 32)
+                                       ? SSDATA (character)
+                                     : "\\?"));
+                  skip_p = true;
+                  break;
+                }
+              case IMAGE_GLYPH:
+                break;
+            }
+            beg += 1;
+          }
+
+      if (i >= 0
+          && !skip_p)
+
+/* *************************************************************************** */
+
+
 	{
 	  enum draw_glyphs_face overlap_hl;
 
@@ -27069,6 +32447,24 @@ append_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       if (it->pixel_width > 0)
@@ -27152,6 +32548,24 @@ append_composite_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[it->area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = it->cmp_it.charpos;
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -27360,6 +32774,24 @@ produce_image_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27463,6 +32895,24 @@ produce_xwidget_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27549,6 +32999,24 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
 	    width -= it->first_visible_x - it->current_x;
 	  eassert (width > 0);
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = object;
       /* FIXME: It would be better to use TYPE_MAX here, but
@@ -28003,6 +33471,24 @@ append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      glyph->x = it->current_x;
+
+      glyph->y = it->current_y;
+
+      glyph->hpos = it->hpos;
+
+      glyph->vpos = it->vpos;
+
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -29769,9 +35255,32 @@ display_and_set_cursor (struct window *w, bool on,
       w->phys_cursor.vpos = vpos;
     }
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  w->mc.h = -1;
+  w->mc.fx = -1;
+  w->mc.fy = -1;
+  w->mc.glyph_flavor = NO_FLAVOR;
+  w->mc.red = -1.0;
+  w->mc.green = -1.0;
+  w->mc.blue = -1.0;
+  w->mc.posint = -1;
+
   FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
                                      new_cursor_type, new_cursor_width,
                                      on, active_cursor);
+
+  mc_multiple_cursors_portal (w, on, active_cursor);
+
+  mc_crosshairs_portal (w, on, active_cursor);
+
+  mc_fill_column_portal (w, on, active_cursor);
+
+/* *************************************************************************** */
+
+
 }
 
 
@@ -32528,6 +38037,28 @@ x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
 void
 syms_of_xdisp (void)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  defsubr (&Smc_dump_glyph_row);
+
+  defsubr (&Smc_dump_glyph_matrix);
+
+  defsubr (&Smc_activate_multiple_cursors);
+
+  defsubr (&Smc_activate_crosshairs);
+
+  defsubr (&Smc_stderr);
+
+  defsubr (&Smc_debug);
+
+  defsubr (&Smc_activate_fill_column);
+
+/* *************************************************************************** */
+
+
   Vwith_echo_area_save_vector = Qnil;
   staticpro (&Vwith_echo_area_save_vector);
 
diff --git a/src/xterm.c b/src/xterm.c
index 3a7e31e..1e9492b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -992,6 +992,15 @@ x_update_begin (struct frame *f)
   if (FRAME_TOOLTIP_P (f) && !FRAME_VISIBLE_P (f))
     return;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = f;
+
+/* *************************************************************************** */
+
+
   if (! FRAME_CR_SURFACE (f))
     {
       int width, height;
@@ -1258,6 +1267,16 @@ x_update_end (struct frame *f)
   XFlush (FRAME_X_DISPLAY (f));
   unblock_input ();
 #endif
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  f->mc_updating_frame = NULL;
+
+/* *************************************************************************** */
+
+
 }
 
 /* This function is called from various places in xdisp.c
@@ -1530,6 +1549,20 @@ static void x_check_font (struct frame *, struct font *);
 static void
 x_set_cursor_gc (struct glyph_string *s)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+  if (s->w->mc.cursor_gc_default)
+    {
+      s->gc = s->f->output_data.x->cursor_gc;
+      return;
+    }
+
+/* *************************************************************************** */
+
+
   if (s->font == FRAME_FONT (s->f)
       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
@@ -9252,6 +9285,26 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 
   /* Compute frame-relative coordinates for phys cursor.  */
   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+/* LEGEND:
+
+-  top y == WINDOW_TO_FRAME_PIXEL_Y (w, row->y)
+
+-  bottom y == WINDOW_TO_FRAME_PIXEL_Y (w, row->y) - row->height
+
+-  h of HOLLOW_BOX_CURSOR == row->height
+   [This avoids a visible gap above/below.] */
+
+  if (w->mc.h > 0)
+    h = row->height;
+
+/* *************************************************************************** */
+
+
   wd = w->phys_cursor_width - 1;
 
   /* The foreground of cursor_gc is typically the same as the normal
@@ -9328,7 +9381,17 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
 	 invisible.  Use the glyph's foreground color instead in this
 	 case, on the assumption that the glyph's colors are chosen so
 	 that the glyph is legible.  */
-      if (face->background == f->output_data.x->cursor_pixel)
+
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+      if (face->background == f->output_data.x->cursor_pixel
+          && !w->mc.cursor_gc_invisible_okay)
+
+/* *************************************************************************** */
+
+
 	xgcv.background = xgcv.foreground = face->foreground;
       else
 	xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
@@ -9359,6 +9422,17 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
 	  if ((cursor_glyph->resolved_level & 1) != 0)
 	    x += cursor_glyph->pixel_width - width;
 
+
+/* *************************************************************************** */
+/* MULTIPLE CURSORS */
+
+    /* Align all fake BAR_CURSOR of the VERTICAL_RULER with `opoint_x'. */
+    if (w->mc.fx > 0)
+      x = w->mc.fx;
+
+/* *************************************************************************** */
+
+
 	  x_fill_rectangle (f, gc, x,
 			  WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
 			  width, row->height);
@@ -9435,31 +9509,173 @@ 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;
+/* *************************************************************************** */
+/* begin MULTIPLE CURSORS */
 
-	    case HBAR_CURSOR:
-	      x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
-	      break;
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+  Colormap cmap = FRAME_X_COLORMAP (f);
+  unsigned long original_cursor_pixel = f->output_data.x->cursor_pixel;
+  /* xterm.c/xterm.h use GC; whereas, w32term.c/w32term.h use XGCValues * */
+  GC original_cursor_gc = f->output_data.x->cursor_gc;
+  double base = 65535.0;
+  double term_red = base * w->mc.red;
+  double term_green = base * w->mc.green;
+  double term_blue = base * w->mc.blue;
+  int int_red = XFIXNUM (Ftruncate (make_float (term_red), Qnil));
+  int int_green = XFIXNUM (Ftruncate (make_float (term_green), Qnil));;
+  int int_blue = XFIXNUM (Ftruncate (make_float (term_blue), Qnil));;
+  XColor color;
+  color.red = int_red;
+  color.green = int_green;
+  color.blue = int_blue;
+  /* `x_alloc_nearest_color' sets the `color.pixel`. */
+  x_alloc_nearest_color (f, cmap, &color);
+  switch (cursor_type)
+  {
+    case HOLLOW_BOX_CURSOR:
+    {
+      struct glyph *glyph = get_phys_cursor_glyph (w);
+      if (glyph == NULL)
+        return;
+      if (glyph->type != IMAGE_GLYPH && w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
+          Lisp_Object buf = w->contents;
+          CHECK_BUFFER (buf);
+          struct buffer *b = XBUFFER (buf);
+          bool region_active_p = (!NILP (Vtransient_mark_mode)
+                                  && !NILP (BVAR (b, mark_active)));
+          ptrdiff_t region_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+          ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+          bool region_in_bounds_p = (region_active_p
+                                     && w->mc.posint >= region_beginning
+                                     && w->mc.posint < region_end);
+          /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in xfns.c.  */
+          if (region_active_p
+              && region_in_bounds_p
+              && active_p)
+            {
+              enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+              struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+              XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, default_face->foreground);
+              XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_face->background);
+            }
+            else if (region_active_p
+                     && !region_in_bounds_p
+                     && active_p)
+              {
+                enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, default_face->foreground);
+                XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_out_face->foreground);
+              }
+              else if (!region_active_p && active_p)
+                {
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, default_face->foreground);
+                  XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->background);
+                }
+                /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                else if (!active_p)
+                  {
+                    enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                    struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                    XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, default_face->foreground);
+                    XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_inactive_face->background);
+                  }
+          block_input ();
+          /* Force `x_set_cursor_gc' to use `s->f->output_data.x->cursor_gc'.  */
+          w->mc.cursor_gc_default = true;
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+          w->mc.cursor_gc_default = false;
+          f->output_data.x->cursor_gc = original_cursor_gc;
+          unblock_input ();
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+          f->output_data.x->cursor_pixel = color.pixel;
+          x_draw_hollow_cursor (w, glyph_row);
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else if (glyph->type == IMAGE_GLYPH && w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+          {
+            /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+            f->output_data.x->cursor_pixel = color.pixel;
+            x_draw_hollow_cursor (w, glyph_row);
+            f->output_data.x->cursor_pixel = original_cursor_pixel;
+          }
+          else
+            x_draw_hollow_cursor (w, glyph_row);
+      break;
+    }
+    case FILLED_BOX_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+        functionality of `x_make_gc' in xfns.c.  */
+        {
+          block_input ();
+          XGCValues gc_values;
+          unsigned long mask = GCForeground | GCBackground | GCFillStyle | GCLineWidth;
+          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);
+          /* Force `x_set_cursor_gc' to use `s->f->output_data.x->cursor_gc'.  */
+          w->mc.cursor_gc_default = true;
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+          w->mc.cursor_gc_default = false;
+          f->output_data.x->cursor_gc = original_cursor_gc;
+          unblock_input ();
+        }
+        else
+          draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
+      break;
+    }
+    case BAR_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+          f->output_data.x->cursor_pixel = color.pixel;
+          w->mc.cursor_gc_invisible_okay = true;
+          x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+          w->mc.cursor_gc_invisible_okay = false;
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+      break;
+    }
+    case HBAR_CURSOR:
+    {
+      if (w->mc.red >= 0 && w->mc.blue >= 0 && w->mc.green >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'.  */
+          f->output_data.x->cursor_pixel = color.pixel;
+          w->mc.cursor_gc_invisible_okay = true;
+          x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
+          w->mc.cursor_gc_invisible_okay = false;
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        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 ();
+  }
+
+/* end MULTIPLE CURSORS */
+/* *************************************************************************** */
 
-	    case NO_CURSOR:
-	      w->phys_cursor_width = 0;
-	      break;
 
-	    default:
-	      emacs_abort ();
-	    }
 	}
 
 #ifdef HAVE_X_I18N
@@ -10644,7 +10860,7 @@ get_current_wm_state (struct frame *f,
   int rc, actual_format;
   Atom actual_type;
   unsigned char *tmp_data = NULL;
-  Atom *reply_data UNINIT;
+  Atom *reply_data;
 #endif
 
   *sticky = false;
