diff --git a/lisp/crosshairs.el b/lisp/crosshairs.el
new file mode 100644
index 0000000..782752f
--- /dev/null
+++ b/lisp/crosshairs.el
@@ -0,0 +1,1288 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 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/pop-state-from-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")
+(declare-function mc/all-fake-cursors "ext:multiple-cursors-core")
+(declare-function mc--reset-read-prompts "ext:multiple-cursors-core")
+
+(defmacro mc/save-excursion (&rest forms)
+  "Saves and restores all the state that multiple-cursors cares about."
+  (let ((cs (make-symbol "current-state")))
+    `(let ((,cs (mc/store-current-state-in-overlay
+                 (make-overlay (point) (point) nil nil t))))
+       (overlay-put ,cs 'type 'original-cursor)
+       (save-excursion ,@forms)
+       (mc/pop-state-from-overlay ,cs))))
+
+;;;###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 'mc-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-command-for-all-fake-cursors (cmd)
+    "Calls CMD interactively for each cursor.
+  It works by moving point to the fake cursor, setting
+  up the proper environment, and then removing the cursor.
+  After executing the command, it sets up a new fake
+  cursor with updated info."
+    (mc/save-excursion
+      ;;; Omit `mc/save-window-scroll' because it causes non-selected windows
+      ;;; to be redisplayed, resulting in undue slowdown of crosshairs.
+      (mapc `(lambda (cursor)
+               (save-excursion
+                 (mc/execute-command-for-fake-cursor cmd cursor)))
+            (mc/all-fake-cursors)))
+    (mc--reset-read-prompts))
+
+  (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 mc-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)
+
+  (message "mc/built-in-cursors:  The multiple-cursors library is ready to use."))
+
+;;;###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))
+
+;; (eval-after-load "multiple-cursors-core"
+;;   '(progn
+;;      (mc/built-in-cursors)))
+
+(cond
+  ((and (locate-library "multiple-cursors-core")
+        (not (featurep 'multiple-cursors-core)))
+    (require 'multiple-cursors-core)
+    (mc/built-in-cursors))
+  ((featurep 'multiple-cursors-core)
+    (mc/built-in-cursors)))
+
+;;; END modification of the Multiple Cursors library written by  Magnar Sveen.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; BEGIN crosshairs.el
+
+;;; Built-in buffer-local variables defined in `buffer.c`:
+
+;;;  `mc-real-fake-cursor'
+;;;  `mc-conf'
+;;;  `mc-inactive-windows'
+;;;  `crosshairs'
+;;;  `ch-horizontal-ruler'
+;;;  `ch-vertical-ruler'
+;;;  `ch-inactive-windows'
+;;;  `mc-stderr'
+;;;  `fc-visible'
+;;;  `fc-inactive-window'
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 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 "ForestGreen")))
+  "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 `fc-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 +-forthwith nil
+  "If non-nil, then the functions will run on the `post-command-hook';
+otherwise, the functions will run on the idle-timer.")
+(make-variable-buffer-local '+-forthwith)
+
+(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 the functions attached to the idle-timer
+if `+-forthwith' is non-nil.")
+(make-variable-buffer-local '+-idle-timer-seconds)
+
+(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-p t
+  "Draw/erase matching parentheses when non-nil.")
+(make-variable-buffer-local '+-parens-p)
+
+(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
+
+(defvar compilation-scroll-output)
+
+;;;###autoload
+(defun mc-hello-world ()
+(interactive)
+  (setq compilation-scroll-output t)
+  (compile "while :; do echo \"Hello-World\"; sleep 1; done"))
+
+;;;###autoload
+(defun mc-test ()
+"Draw fake cursors at all POS defined in the `mc-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_calc' 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 mc-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])
+                      (7 "framed" "OrangeRed")
+                      (8 "box" "grey25")
+                      (9 "box" "grey75"))))
+    (select-window (display-buffer buffer))))
+
+(defun +-timer-fn ()
+"Since this fires globally, we must control which buffers crosshairs appear in."
+  (when +-mode
+    (unless (or (memq last-command +-parens-exclusions)
+                (null +-parens-p))
+      (+-parens-fn))
+    (when +-timer-var
+      (setq timer-idle-list (delq +-timer-var timer-idle-list))
+      (setq +-timer-var nil))))
+
+(defun +-draw-forthwith ()
+"Immediately delete/draw matching parentheses."
+  (+-draw-crosshairs 'force))
+
+(defun +-draw-crosshairs (&optional force)
+"Immediately delete matching parentheses.  If FORCE is non-nil, then immediately
+draw matching parenthesis; otherwise, draw them on an idle-tier."
+  (when +-mode
+    (when +-timer-var
+      (setq timer-idle-list (delq +-timer-var timer-idle-list))
+      (setq +-timer-var nil))
+    (unless (or (memq this-command +-parens-exclusions)
+                (and (null +-parens-p)
+                     (null +-parens-overlays-exist-p)))
+      (+-delete-parens-overlays))
+    (if force
+      (progn
+        (when +-parens-p
+          (+-parens-fn)))
+      (setq +-timer-var (run-with-idle-timer +-idle-timer-seconds nil #'+-timer-fn)))))
+
+(defvar fc-mode)
+
+;;;###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 fc-mode
+        (fc-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)))
+      (setq crosshairs t)
+      (when +-fill-column
+        (setq fc-visible 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))
+      (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 (or +-forthwith
+              (equal current-prefix-arg '(4)))
+        (add-hook 'post-command-hook '+-draw-forthwith 'append 'local)
+        (add-hook 'post-command-hook '+-draw-crosshairs 'append 'local))
+      (when +-forthwith
+        (add-hook 'window-configuration-change-hook '+-draw-forthwith nil 'local))
+      (add-hook 'change-major-mode-hook 'turn-off-+-mode nil 'local)
+      ;;; Matching parentheses drawing forthwith interferes with yasnippet.
+      (when +-forthwith
+        (setq +-parens-p nil))
+      (when (called-interactively-p 'any)
+        (cond
+          (+-forthwith
+            (message "Turned ON `+-mode' -- Draw matching parentheses immediately."))
+          ((equal current-prefix-arg '(4))
+            ;;; Matching parentheses will be drawn immediately.
+            (message "Turned ON `+-mode' -- Optimized for debugging purposes."))
+          (t
+            (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 'fc-visible)
+      (kill-local-variable 'display-line-numbers)
+      (kill-local-variable 'display-line-numbers-width)
+      (kill-local-variable 'mc-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)
+      (kill-local-variable '+-forthwith)
+      (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 fc-mode)
+
+(defvar fc-timer-var nil
+"Timer used to highlight current column whenever Emacs is idle.")
+
+;;;###autoload
+(define-minor-mode fc-mode
+"Minor mode for displaying a visual fill column."
+  :init-value nil
+  :lighter " FC"
+  :keymap nil
+  :global nil
+  :group 'fc-mode
+  (cond
+    ;;; `+-mode' has the ability to also display a fill column indicator.
+    ;;; See the variable `+-fill-column'.
+    ((and fc-mode +-mode)
+      (setq fc-mode nil)
+      (message "Turned OFF `fc-mode' (%s) -- see the variable `+-fill-column'." (current-buffer)))
+    (fc-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)))
+      (setq fc-visible 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)
+        (add-hook 'change-major-mode-hook 'turn-off-fc-mode nil 'local))
+      (when (called-interactively-p 'any)
+        (if (equal current-prefix-arg '(4))
+          (message "Turned ON `fc-mode' -- debugging mode.")
+          (message "Turned ON `fc-mode'."))))
+    (t
+      (kill-local-variable 'fill-column)
+      (kill-local-variable 'fc-visible)
+      (remove-hook 'change-major-mode-hook 'turn-off-fc-mode 'local)
+      (when (called-interactively-p 'any)
+        (message "Turned OFF `fc-mode'.")))))
+
+(defun turn-off-fc-mode ()
+  (fc-mode -1))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'crosshairs)
diff --git a/lisp/faces.el b/lisp/faces.el
index fa526c3..b3f747e 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2500,6 +2500,634 @@ unwanted effects."
   :group 'basic-faces
   :group 'display-line-numbers)
 
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; begin MULTIPLE-CURSORS
+
+(defface +-debugging-face
+  '((t (:foreground "OrangeRed")))
+  "Face for `+-debugging-face'."
+  :group '+-mode)
+
+(defface +-special-character-face
+  '((t (:foreground "cyan")))
+  "Face for `+-special-character-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-pre-zv-face
+  '((t (:foreground "red")))
+  "Face for `+-overlay-arrow-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-inactive-pre-zv-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-inactive-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-pre-zv-face
+  '((t (:foreground "DarkGreen")))
+  "Face for `+-overlay-arrow-hscl-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-inactive-pre-zv-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-hscl-inactive-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "cyan" :background "DarkBlue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "magenta" :background "LightSkyBlue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "cyan" :background "DarkBlue")
+    (((class color) (min-colors 16) (background light))
+     :foreground "magenta" :background "LightSkyBlue")
+    (((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-pre-zv-face'.
+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-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff00ff" :background "ForestGreen")
+    (((class color) (min-colors 88) (background light))
+     :foreground "OrangeRed" :background "grey70")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "#ff00ff" :background "ForestGreen")
+    (((class color) (min-colors 16) (background light))
+     :foreground "OrangeRed" :background "grey70")
+    (((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-pre-zv-face'.
+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-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "red" :background "DarkBlue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "cyan" :background "LightSkyBlue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "red" :background "DarkBlue")
+    (((class color) (min-colors 16) (background light))
+     :foreground "cyan" :background "LightSkyBlue")
+    (((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-at-zv-face'.
+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-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "blue" :background "ForestGreen")
+    (((class color) (min-colors 88) (background light))
+     :foreground "blue" :background "grey70")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "blue" :background "ForestGreen")
+    (((class color) (min-colors 16) (background light))
+     :foreground "blue" :background "grey70")
+    (((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-at-zv-face'.
+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 '+-modeo)
+
+(defface +-real-fake-cursor-at-region-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "chocolate4" :background "#8b795e")
+    (((class color) (min-colors 88) (background light))
+     :foreground "pink" :background "black")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "chocolate4" :background "#8b795e")
+    (((class color) (min-colors 16) (background light))
+     :foreground "pink" :background "black")
+    (((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-at-region-pre-zv-face'.
+As to a hollow style cursor, the `:foreground` parameter is used for the inner
+filled shading when `cursor_glyph->charpos` is _at_ the region beginning; the
+`:background` parameter is used for the inner filled shading when
+`cursor_glyph->charpos` is _at_ the region end.  The character retains its own
+foreground color and is unaffected by this face."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-in-region-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "orange")
+    (((class color) (min-colors 88) (background light))
+     :foreground "purple")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "orange")
+    (((class color) (min-colors 16) (background light))
+     :foreground "purple")
+    (((class color) (min-colors 8))
+     :foreground "gray50")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "purple"))
+  "Face for `+-real-fake-cursor-in-region-pre-zv-face'.
+As to a hollow style cursor, the `:foreground` parameter is used for the inner
+filled shading when `cursor_glyph->charpos` is _in_ the region beginning.  The
+character retains its own foreground color and is unaffected by this face."
+  :group '+-mode)
+
+(defface +-bar-pre-zv-face
+  '((t (:foreground "magenta1")))
+  "Face for `+-bar-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-bar-at-zv-face
+  '((t (:foreground "yellow")))
+  "Face for `+-bar-at-zv-face'."
+  :group '+-mode)
+
+(defface +-bar-post-zv-face
+  '((t (:foreground "magenta4")))
+  "Face for `+-bar-post-zv-face'."
+  :group '+-mode)
+
+(defface +-reversed-bar-pre-zv-face
+  '((t (:foreground "cyan1")))
+  "Face for `+-reversed-bar-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-reversed-bar-at-zv-face
+  '((t (:foreground "chartreuse")))
+  "Face for `+-reversed-bar-at-zv-face'."
+  :group '+-mode)
+
+(defface +-reversed-bar-post-zv-face
+  '((t (:foreground "cyan4")))
+  "Face for `+-reversed-bar-post-zv-face'."
+  :group '+-mode)
+
+(defface +-even-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 88) (background light))
+     :foreground "cyan1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "cyan1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-even-inactive-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#eee8aa")
+    (((class color) (min-colors 88) (background light))
+     :foreground "blue1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "#eee8aa")
+    (((class color) (min-colors 16) (background light))
+     :foreground "blue1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-inactive-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-even-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DeepPink1")
+    (((class color) (min-colors 88) (background light))
+     :foreground "DeepPink1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "DeepPink1")
+    (((class color) (min-colors 16) (background light))
+     :foreground "DeepPink1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-at-zv-face'."
+  :group '+-mode)
+
+(defface +-even-inactive-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DeepPink4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "DeepPink4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "DeepPink4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "DeepPink4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-inactive-at-zv-face'."
+  :group '+-mode)
+
+(defface +-even-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DarkOliveGreen3")
+    (((class color) (min-colors 88) (background light))
+     :foreground "cyan4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "DarkOliveGreen3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "cyan4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-post-zv-face'."
+  :group '+-mode)
+
+(defface +-even-inactive-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DarkOliveGreen4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "RoyalBlue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "DarkOliveGreen4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "RoyalBlue")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-inactive-post-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "red1")
+    (((class color) (min-colors 88) (background light))
+     :foreground "red1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "red1")
+    (((class color) (min-colors 16) (background light))
+     :foreground "red1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-inactive-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff6347")
+    (((class color) (min-colors 88) (background light))
+     :foreground "#ff6347")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "#ff6347")
+    (((class color) (min-colors 16) (background light))
+     :foreground "#ff6347")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-inactive-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "SteelBlue3")
+    (((class color) (min-colors 88) (background light))
+     :foreground "SteelBlue3")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "SteelBlue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "SteelBlue3")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-at-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-inactive-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "SteelBlue4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "SteelBlue4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "SteelBlue4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "SteelBlue4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-inactive-at-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "sienna1")
+    (((class color) (min-colors 88) (background light))
+     :foreground "DarkSalmon")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "sienna1")
+    (((class color) (min-colors 16) (background light))
+     :foreground "DarkSalmon")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-post-zv-face'."
+  :group '+-mode)
+
+(defface +-odd-inactive-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "sienna4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "sienna4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "sienna4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "sienna4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-inactive-post-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "green1")
+    (((class color) (min-colors 88) (background light))
+     :foreground "green1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "green1")
+    (((class color) (min-colors 16) (background light))
+     :foreground "green1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-inactive-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "green4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "green4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "green4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "green4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-inactive-pre-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "purple3")
+    (((class color) (min-colors 88) (background light))
+     :foreground "red1")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "purple3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "red1")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-at-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-inactive-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "purple4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "red4")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "purple4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "red4")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-inactive-at-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "PaleGreen3")
+    (((class color) (min-colors 88) (background light))
+     :foreground "PaleGreen3")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "PaleGreen3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "PaleGreen3")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-post-zv-face'."
+  :group '+-mode)
+
+(defface +-post-fill-inactive-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "PaleGreen4")
+    (((class color) (min-colors 88) (background light))
+     :foreground "DarkOliveGreen")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "PaleGreen4")
+    (((class color) (min-colors 16) (background light))
+     :foreground "DarkOliveGreen")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-post-fill-inactive-post-zv-face'."
+  :group '+-mode)
+
+(defface fc-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "grey15")
+    (((class color) (min-colors 88) (background light))
+     :foreground "grey15")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "grey15")
+    (((class color) (min-colors 16) (background light))
+     :foreground "grey15")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-pre-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-inactive-pre-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "blue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "grey60")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "blue")
+    (((class color) (min-colors 16) (background light))
+     :foreground "grey60")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-inactive-pre-zv-face' in the inactive window."
+  :group '+-mode)
+
+(defface fc-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "OrangeRed")
+    (((class color) (min-colors 88) (background light))
+     :foreground "OrangeRed")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "OrangeRed")
+    (((class color) (min-colors 16) (background light))
+     :foreground "OrangeRed")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-at-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-inactive-at-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 88) (background light))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "yellow")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-inactive-at-zv-face' in the inactive window."
+  :group '+-mode)
+
+(defface fc-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "gray40")
+    (((class color) (min-colors 88) (background light))
+     :foreground "grey55")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "gray40")
+    (((class color) (min-colors 16) (background light))
+     :foreground "grey55")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-post-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-inactive-post-zv-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DarkBlue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "grey85")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "DarkBlue")
+    (((class color) (min-colors 16) (background light))
+     :foreground "grey85")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-inactive-post-zv-face' in the inactive window."
+  :group '+-mode)
+
+(defface fc-opoint-pre-zv-face
+  '((t (:foreground "magenta1")))
+  "Face for `fc-opoint-pre-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-opoint-inactive-pre-zv-face
+  '((t (:foreground "magenta4")))
+  "Face for `fc-opoint-inactive-pre-zv-face' in the inactive window."
+  :group '+-mode)
+
+(defface fc-opoint-at-zv-face
+  '((t (:foreground "cyan1")))
+  "Face for `fc-opoint-at-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-opoint-inactive-at-zv-face
+  '((t (:foreground "cyan4")))
+  "Face for `fc-opoint-inactive-at-zv-face' in the inactive window."
+  :group '+-mode)
+
+(defface fc-opoint-post-zv-face
+  '((t (:foreground "purple3")))
+  "Face for `fc-opoint-post-zv-face' in the active window."
+  :group '+-mode)
+
+(defface fc-opoint-inactive-post-zv-face
+  '((t (:foreground "purple4")))
+  "Face for `fc-opoint-inactive-post-zv-face' in the inactive window."
+  :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 ab47748..4aa745a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -133,6 +133,69 @@ CHECK_OVERLAY (Lisp_Object x)
 
 /* These setters are used only in this file, so they can be private.
    The public setters are inline functions defined in buffer.h.  */
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+static void
+bset_mc_real_fake_cursor (struct buffer *b, Lisp_Object val)
+{
+  b->mc_real_fake_cursor_ = val;
+}
+
+static void
+bset_mc_conf (struct buffer *b, Lisp_Object val)
+{
+  b->mc_conf_ = val;
+}
+
+static void
+bset_mc_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->mc_inactive_windows_ = val;
+}
+
+static void
+bset_crosshairs (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_ = val;
+}
+
+static void
+bset_ch_horizontal_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->ch_horizontal_ruler_ = val;
+}
+
+static void
+bset_ch_vertical_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->ch_vertical_ruler_ = val;
+}
+
+static void
+bset_ch_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->ch_inactive_windows_ = val;
+}
+
+static void
+bset_fc_visible (struct buffer *b, Lisp_Object val)
+{
+  b->fc_visible_ = val;
+}
+
+static void
+bset_fc_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->fc_inactive_windows_ = val;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 static void
 bset_abbrev_mode (struct buffer *b, Lisp_Object val)
 {
@@ -5142,6 +5205,24 @@ 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, mc_conf), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, mc_inactive_windows), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, crosshairs), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, ch_horizontal_ruler), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, ch_vertical_ruler), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, ch_inactive_windows), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, fc_visible), idx); ++idx;
+  XSETFASTINT (BVAR (&buffer_local_flags, fc_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;
@@ -5228,6 +5309,24 @@ init_buffer_once (void)
   /* Must do these before making the first buffer! */
 
   /* real setup is done in bindings.el */
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  bset_mc_real_fake_cursor (&buffer_defaults, Qhollow);
+  bset_mc_conf (&buffer_defaults, Qnil);
+  bset_mc_inactive_windows (&buffer_defaults, Qt);
+  bset_crosshairs (&buffer_defaults, Qnil);
+  bset_ch_horizontal_ruler (&buffer_defaults, Qt);
+  bset_ch_vertical_ruler (&buffer_defaults, Qt);
+  bset_ch_inactive_windows (&buffer_defaults, Qt);
+  bset_fc_visible (&buffer_defaults, Qnil);
+  bset_fc_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);
@@ -5458,6 +5557,51 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
 void
 syms_of_buffer (void)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  DEFSYM (Qmc_real_fake_cursor, "mc-real-fake-cursor");
+  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. */);
+
+  DEFSYM (Qmc_conf, "mc-conf");
+  DEFVAR_PER_BUFFER ("mc-conf", &BVAR (current_buffer, mc_conf), Qnil,
+    doc: /* A bufer-local variable to store the value of the multiple cursors to be displayed
+during the next redisplay. */);
+
+  DEFSYM (Qmc_inactive_windows, "mc-inactive-windows");
+  DEFVAR_PER_BUFFER ("mc-inactive-windows", &BVAR (current_buffer, mc_inactive_windows), Qnil,
+    doc: /* When non-nil, draw multiple cursors in inactive windows. */);
+
+  DEFSYM (Qcrosshairs, "crosshairs");
+  DEFVAR_PER_BUFFER ("crosshairs", &BVAR (current_buffer, crosshairs), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate crosshairs. */);
+
+  DEFSYM (Qch_horizontal_ruler, "ch-horizontal-ruler");
+  DEFVAR_PER_BUFFER ("ch-horizontal-ruler", &BVAR (current_buffer, ch_horizontal_ruler), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate the crosshairs horizontal ruler. */);
+
+  DEFSYM (Qch_vertical_ruler, "ch-vertical-ruler");
+  DEFVAR_PER_BUFFER ("ch-vertical-ruler", &BVAR (current_buffer, ch_vertical_ruler), Qnil,
+    doc: /* A bufer-local variable to activate/deactivate the crosshairs vertical ruler. */);
+
+  DEFSYM (Qch_inactive_windows, "ch-inactive-windows");
+  DEFVAR_PER_BUFFER ("ch-inactive-windows", &BVAR (current_buffer, ch_inactive_windows), Qnil,
+    doc: /* When non-nil, draw crosshairs in inactive windows. */);
+
+  DEFSYM (Qfc_visible, "fc-visible");
+  DEFVAR_PER_BUFFER ("fc-visible", &BVAR (current_buffer, fc_visible), Qnil,
+    doc: /* A bufer-local variable to turn on/off the multiple cursors fill column. */);
+
+  DEFSYM (Qfc_visible_inactive_window, "fc-inactive-window");
+  DEFVAR_PER_BUFFER ("fc-inactive-windows", &BVAR (current_buffer, fc_inactive_windows), Qnil,
+    doc: /* When non-nil, draw multiple cursors fill column in inactive windows. */);
+
+/* *************************************************************************** */
+
+
   staticpro (&last_overlay_modification_hooks);
   last_overlay_modification_hooks = make_nil_vector (10);
 
diff --git a/src/buffer.h b/src/buffer.h
index f42c3e9..189fac5 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -736,6 +736,40 @@ struct buffer
      in the display of this buffer.  */
   Lisp_Object extra_line_spacing_;
 
+
+/* *************************************************************************** */
+/* 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 mc_conf_;
+
+  /* Whether to draw multiple cursors in inactive windows. */
+  Lisp_Object mc_inactive_windows_;
+
+  /* The name of the buffer-local variable. */
+  Lisp_Object crosshairs_;
+
+  /* The name of the crosshairs horizontal ruler. */
+  Lisp_Object ch_horizontal_ruler_;
+
+  /* The name of the crosshairs vertical ruler. */
+  Lisp_Object ch_vertical_ruler_;
+
+  /* Whether to draw crosshairs in inactive windows. */
+  Lisp_Object ch_inactive_windows_;
+
+  /* The name of the buffer-local variable. */
+  Lisp_Object fc_visible_;
+
+  /* Whether to draw multiple cursors fill column in inactive windows. */
+  Lisp_Object fc_inactive_windows_;
+
+/* *************************************************************************** */
+
+
   /* Cursor type to display in non-selected windows.
      t means to use hollow box cursor.
      See `cursor-type' for other values.  */
@@ -787,14 +821,21 @@ struct buffer
      an indirect buffer since it counts as its base buffer.  */
   int window_count;
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
   /* A non-zero value in slot IDX means that per-buffer variable
      with index IDX has a local value in this buffer.  The index IDX
      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
+#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 ==
@@ -903,6 +944,69 @@ 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.)  */
+
+
+/* *************************************************************************** */
+/* begin 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_mc_conf (struct buffer *b, Lisp_Object val)
+{
+  b->mc_conf_ = val;
+}
+
+INLINE void
+bset_blv_mc_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->mc_inactive_windows_ = val;
+}
+
+INLINE void
+bset_blv_crosshairs (struct buffer *b, Lisp_Object val)
+{
+  b->crosshairs_ = val;
+}
+
+INLINE void
+bset_blv_ch_horizontal_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->ch_horizontal_ruler_ = val;
+}
+
+INLINE void
+bset_blv_ch_vertical_ruler (struct buffer *b, Lisp_Object val)
+{
+  b->ch_vertical_ruler_ = val;
+}
+
+INLINE void
+bset_blv_ch_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->ch_inactive_windows_ = val;
+}
+
+INLINE void
+bset_blv_fc_visible (struct buffer *b, Lisp_Object val)
+{
+  b->fc_visible_ = val;
+}
+
+INLINE void
+bset_blv_fc_inactive_windows (struct buffer *b, Lisp_Object val)
+{
+  b->fc_inactive_windows_ = val;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 INLINE void
 bset_bidi_paragraph_direction (struct buffer *b, Lisp_Object val)
 {
diff --git a/src/dispextern.h b/src/dispextern.h
index 1a53656..4d767ea 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -100,6 +100,129 @@ typedef int Cursor;
 #define NativeRectangle int
 #endif
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+struct glyph;
+
+struct glyph_row;
+
+struct glyph_matrix;
+
+enum draw_glyphs_face;
+
+enum glyph_row_area;
+
+struct mc_matrix;
+
+enum mc_cache_type;
+
+enum mc_cursor_type;
+
+enum mc_flavor;
+
+struct mc_RGB;
+
+struct mc_essentials;
+
+enum mc_draw_row_type;
+
+enum mc_engine_type;
+
+enum mc_row_position;
+
+enum mc_redraw_row_type;
+
+enum draw_glyph_action;
+
+extern Lisp_Object mc_listn (ptrdiff_t, Lisp_Object, ...);
+
+extern Lisp_Object mc_nth (int, Lisp_Object);
+
+extern Lisp_Object mc_assq (Lisp_Object, Lisp_Object);
+
+extern enum mc_row_position mc_row_position (struct window *, struct glyph_row *,
+                                             struct glyph_row *, int);
+
+extern ptrdiff_t mc_region_limit (bool);
+
+extern struct glyph * mc_get_cursor_glyph (struct window *, struct glyph_matrix *,
+                                           struct glyph_row *, int, int);
+
+extern void mc_xw_color_values (struct window *, Lisp_Object, struct mc_RGB *);
+
+extern bool mc_update_window_fringes (struct window *, bool);
+
+extern char * mc_window (struct window *);
+
+extern char * mc_char_to_string (int);
+
+extern char * mc_cursor_type_to_string (enum mc_cursor_type);
+
+extern char * mc_flavor_to_string (enum mc_flavor);
+
+extern char * mc_cache_type_to_string (enum mc_cache_type);
+
+extern char * mc_redraw_row_type_to_string (enum mc_redraw_row_type);
+
+extern void mc_cache_inspector (struct window *, struct mc_matrix);
+
+extern bool mc_traverse_cache_p (struct mc_matrix, enum mc_cache_type, int, int);
+
+extern void mc_draw_fringe_bitmap (struct window *, struct glyph_row *, int,
+                                   enum mc_cursor_type);
+
+extern int mc_get_fringe_bitmap (struct window *, Lisp_Object, int, int);
+
+extern void mc_engine (struct window *, struct glyph_matrix *, struct glyph_row *,
+                       struct glyph *, int, int, int, int, int, int,
+                       enum mc_cursor_type, int, struct glyph_matrix *,
+                       struct mc_essentials, enum mc_row_position, struct mc_RGB,
+                       enum mc_engine_type, bool, enum mc_draw_row_type,
+                       enum mc_cache_type);
+
+extern void mc_set_essentials (struct window *, struct mc_essentials *);
+
+extern void mc_draw_row (struct window *, struct glyph_matrix *, struct glyph_row *,
+                         struct glyph *, int, int, int, struct glyph_matrix *,
+                         struct mc_essentials, enum mc_row_position, bool,
+                         enum mc_draw_row_type);
+
+extern bool mc_redraw_row (struct window *, struct glyph_matrix *, struct glyph_row *,
+                           enum glyph_row_area, int, int, int, bool,
+                           enum draw_glyphs_face, enum mc_redraw_row_type);
+
+extern void mc_reset_cache (struct window *);
+
+extern void mc_draw_cursor_glyph (struct window *, struct glyph_matrix *,
+                                  struct glyph_row *, enum draw_glyphs_face,
+                                  int, int, int, struct mc_RGB, enum mc_flavor,
+                                  enum mc_cursor_type, int, bool, bool);
+
+extern void mc_erase_cursor (struct window *, struct glyph_matrix *, struct glyph_row *,
+                             int, int, int, int, enum mc_flavor,
+                             enum mc_cursor_type, int);
+
+extern void mc_draw_erase_hybrid (struct window *, struct glyph_matrix *, struct glyph_row *,
+                                  int, int, int, int, int, int, int, int,
+                                  enum mc_cursor_type, int, struct mc_RGB,
+                                  bool, enum mc_flavor, bool);
+
+extern int mc_draw_glyphs (struct window *, struct glyph_matrix *, struct glyph_row *,
+                           int, enum glyph_row_area, ptrdiff_t, ptrdiff_t,
+                           enum draw_glyphs_face, int, int, struct mc_RGB,
+                           enum mc_flavor, enum mc_cursor_type, int, bool, bool,
+                           enum draw_glyph_action, bool);
+
+extern struct glyph_matrix * mc_save_glyph_matrix (struct glyph_matrix *);
+
+extern void mc_restore_glyph_matrix (struct glyph_matrix *, struct glyph_matrix *);
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Text cursor types.  */
 
 enum text_cursor_kinds
@@ -382,6 +505,18 @@ struct glyph_slice
 
 struct glyph
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  int relative_x, hpos;
+
+  ptrdiff_t bytepos;
+
+/* *************************************************************************** */
+
+
   /* 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
@@ -1248,6 +1383,28 @@ enum draw_glyphs_face
 
 struct glyph_string
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    bool_bf left_overwritten_p : 1;
+
+    bool_bf right_overwritten_p : 1;
+
+    bool_bf rectangle_nuked_p : 1;
+
+    bool_bf background_nuked_p : 1;
+
+    enum draw_glyph_action
+    {
+      MC_DRAW_GLYPH_STRING,
+      MC_ERASE_GLYPH_STRING
+    } action_type;
+
+/* *************************************************************************** */
+
+
   /* X-origin of the string.  */
   int x;
 
@@ -2812,6 +2969,28 @@ typedef void (*frame_parm_handler) (struct frame *, Lisp_Object, Lisp_Object);
 
 struct redisplay_interface
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* `redisplay_interface' in `nsterm.m` | `w32term.c` | `xterm.c` must be in the
+exact same order as the `redisplay_interface' in `dispextern.h`! */
+
+  /* `mc_ns_draw_window_cursor' | `mc_w32_draw_window_cursor' | `mc_x_draw_window_cursor' */
+  void (*mc_scribe_cursor) (struct window *w, struct glyph_matrix *matrix,
+        struct glyph_row *glyph_row, int x, int fx, int y, int fy, int hpos,
+        int vpos, int wd, int h, struct mc_RGB lsl, enum mc_cursor_type cursor_type,
+        int cursor_width, enum mc_flavor glyph_flavor, bool on_p, bool active_p);
+
+  /* `mc_ns_draw_glyph_string' | `mc_w32_draw_glyph_string' | `mc_x_draw_glyph_string' */
+  void (*mc_scribe_string) (struct glyph_string *s, struct glyph_matrix *matrix, struct glyph_row *row,
+        struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+        enum mc_cursor_type cursor_type, int wd, bool active_p, bool cursor_gc_p);
+
+/* *************************************************************************** */
+
+
   /* Handlers for setting frame parameters.  */
   frame_parm_handler *frame_parm_handlers;
 
diff --git a/src/dispnew.c b/src/dispnew.c
index ccb08ec..5e2808b 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -56,6 +56,1824 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "w32.h"
 #endif
 
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+struct glyphs_skipped
+{
+  ptrdiff_t allocated;
+  ptrdiff_t used;
+  struct skipped_items
+    {
+      int x;
+      int hpos;
+      bool enabled_p;
+    } *skipped;
+} array_glyphs_skipped;
+
+struct mc_row_entry
+{
+  int old_uses, new_uses;
+  int new_line_number;
+  ptrdiff_t bucket;
+  struct glyph_row *row;
+  struct mc_row_entry *next;
+};
+static struct mc_row_entry *mc_row_entry_pool;
+static ptrdiff_t mc_row_entry_pool_size;
+static ptrdiff_t mc_row_entry_idx;
+static struct mc_row_entry **mc_row_table;
+static ptrdiff_t mc_row_table_size;
+static struct mc_row_entry **mc_old_lines, **mc_new_lines;
+static ptrdiff_t mc_old_lines_size, mc_new_lines_size;
+static struct run *mc_run_pool;
+static ptrdiff_t mc_runs_size;
+static struct run **mc_runs;
+
+static bool update_window_line (struct window *, int, bool *);
+
+static void update_marginal_area (struct window *, struct glyph_row *,
+                                  enum glyph_row_area, int);
+
+static void make_current (struct glyph_matrix *, struct glyph_matrix *, int);
+
+static bool row_equal_p (struct glyph_row *, struct glyph_row *, bool);
+
+static void assign_row (struct glyph_row *, struct glyph_row *);
+
+static bool
+mc_verify_row_hash (struct glyph_row *row)
+{
+  return row->hash == row_hash (row);
+}
+
+static struct mc_row_entry *
+mc_add_row_entry (struct glyph_row *row)
+{
+  struct mc_row_entry *entry;
+  ptrdiff_t i = row->hash % mc_row_table_size;
+  entry = mc_row_table[i];
+  eassert (entry || mc_verify_row_hash (row));
+  while (entry && !row_equal_p (entry->row, row, 1))
+    entry = entry->next;
+  if (entry == NULL)
+    {
+      entry = mc_row_entry_pool + mc_row_entry_idx++;
+      entry->row = row;
+      entry->old_uses = entry->new_uses = 0;
+      entry->new_line_number = 0;
+      entry->bucket = i;
+      entry->next = mc_row_table[i];
+      mc_row_table[i] = entry;
+    }
+  return entry;
+}
+
+/* Reverse the contents of rows in MATRIX between START and END.  The
+   contents of the row at END - 1 end up at START, END - 2 at START +
+   1 etc.  This is part of the implementation of rotate_matrix (see
+   below). */
+static void
+mc_reverse_vpos (struct mc_matrix matrix, int start, int end)
+{
+  int i, j;
+  for (i = start, j = end - 1; i < j; ++i, --j)
+    {
+      /* Non-ISO HP/UX compiler doesn't like auto struct initialization. */
+      struct mc_vpos temp;
+      temp = matrix.vpos[i];
+      matrix.vpos[i] = matrix.vpos[j];
+      matrix.vpos[j] = temp;
+    }
+}
+
+/* Rotate the contents of vpos in MATRIX in the range FIRST .. LAST - 1 by BY
+positions.  BY < 0 means rotate left, i.e. towards lower indices.  (Note: this
+does not copy glyphs, only glyph pointers in row structures are moved around).
+The algorithm used for rotating the vector was ... first described by Kernighan.
+See the vector R as consisting of two sub-vectors AB, where A has length BY for
+BY >= 0.  The result after rotating is then BA.  Reverse both sub-vectors to get
+ArBr and reverse the result to get (ArBr)r which is BA.  Similar for rotating right.*/
+void
+mc_rotate_matrix (struct mc_matrix matrix, int first, int last, int by)
+{
+  if (by < 0)
+    {
+      /* Up (rotate left, i.e. towards lower indices). */
+      by = -by;
+      mc_reverse_vpos (matrix, first, first + by);
+      mc_reverse_vpos (matrix, first + by, last);
+      mc_reverse_vpos (matrix, first, last);
+    }
+    else if (by > 0)
+      {
+        /* Down (rotate right, i.e. towards higher indices). */
+        mc_reverse_vpos (matrix, last - by, last);
+        mc_reverse_vpos (matrix, first, last - by);
+        mc_reverse_vpos (matrix, first, last);
+      }
+}
+
+struct mc_matrix
+mc_save_cache_matrix (struct mc_matrix matrix)
+{
+  struct mc_matrix saved;
+  saved.vpos_allocated = matrix.vpos_allocated;
+  saved.vpos_used = matrix.vpos_used;
+  saved.vpos = xzalloc (saved.vpos_allocated * sizeof *saved.vpos);
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    saved.cursors_used[cache_type] = matrix.cursors_used[cache_type];
+  for (int vnth = 0; vnth < matrix.vpos_allocated; ++vnth)
+    {
+      for (enum mc_cache_type cache_type = MC_CACHE;
+           cache_type < NO_CACHE;
+           ++cache_type)
+        {
+          saved.vpos[vnth].cache_allocated[cache_type] = matrix.vpos[vnth].cache_allocated[cache_type];
+          saved.vpos[vnth].cache_used[cache_type] = matrix.vpos[vnth].cache_used[cache_type];
+          if (matrix.vpos[vnth].cache_used[cache_type])
+            {
+              ptrdiff_t nbytes = matrix.vpos[vnth].cache_used[cache_type] * sizeof (struct mc_contents);
+              saved.vpos[vnth].cache[cache_type] = xmalloc (nbytes);
+              memcpy (saved.vpos[vnth].cache[cache_type], matrix.vpos[vnth].cache[cache_type], nbytes);
+            }
+        }
+    }
+  return saved;
+}
+
+void
+mc_xfree_cache_matrix (struct window *w, struct mc_matrix *matrix)
+{
+  if (matrix->vpos == NULL)
+    return;
+  for (int vnth = 0; vnth < matrix->vpos_allocated; ++vnth)
+    {
+      for (enum mc_cache_type cache_type = MC_CACHE;
+           cache_type < NO_CACHE;
+           ++cache_type)
+        if (matrix->vpos[vnth].cache_allocated[cache_type] > 0)
+          {
+            xfree (matrix->vpos[vnth].cache[cache_type]);
+            matrix->vpos[vnth].cache[cache_type] = NULL;
+            matrix->vpos[vnth].cache_allocated[cache_type] = 0;
+            matrix->vpos[vnth].cache_used[cache_type] = 0;
+          }
+    }
+  xfree (matrix->vpos);
+  matrix->vpos = NULL;
+  matrix->vpos_allocated = 0;
+  matrix->vpos_used = 0;
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    matrix->cursors_used[cache_type] = 0;
+}
+
+struct glyph_matrix *
+mc_save_glyph_matrix (struct glyph_matrix *matrix)
+{
+  struct glyph_matrix *saved = xzalloc (sizeof *saved);
+  // NOT_COPIED:  struct glyph_pool *pool;
+  saved->rows_allocated = matrix->rows_allocated;
+  saved->nrows = matrix->nrows;
+  saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
+  saved->matrix_x = matrix->matrix_x;
+  saved->matrix_y = matrix->matrix_y;
+  saved->matrix_w = matrix->matrix_w;
+  saved->matrix_h = matrix->matrix_h;
+  saved->window_pixel_left = matrix->window_pixel_left;
+  saved->window_pixel_top = matrix->window_pixel_top;
+  saved->window_height = matrix->window_height;
+  saved->window_width = matrix->window_width;
+  saved->window_vscroll = matrix->window_vscroll;
+  saved->left_margin_glyphs = matrix->left_margin_glyphs;
+  saved->right_margin_glyphs = matrix->right_margin_glyphs;
+  saved->no_scrolling_p = matrix->no_scrolling_p;
+  saved->header_line_p = matrix->header_line_p;
+#ifdef GLYPH_DEBUG
+  // saved->method = matrix->method;
+#endif
+  // NOT COPIED:  struct buffer *buffer;
+  saved->begv = matrix->begv;
+  saved->zv = matrix->zv;
+  for (int i = 0; i < saved->nrows; ++i)
+    {
+      struct glyph_row *from = matrix->rows + i;
+      struct glyph_row *to = saved->rows + i;
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      to->glyphs[TEXT_AREA] = xmalloc (nbytes);
+      memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
+      to->used[TEXT_AREA] = from->used[TEXT_AREA];
+      to->hash = from->hash;
+      to->x = from->x;
+      to->y = from->y;
+      to->pixel_width = from->pixel_width;
+      to->ascent = from->ascent;
+      to->height = from->height;
+      to->phys_ascent = from->phys_ascent;
+      to->phys_height = from->phys_height;
+      to->visible_height = from->visible_height;
+      to->extra_line_spacing = from->extra_line_spacing;
+      to->start = from->start;
+      to->end = from->end;
+      to->minpos = from->minpos;
+      to->maxpos = from->maxpos;
+      to->overlay_arrow_bitmap = from->overlay_arrow_bitmap;
+      to->left_user_fringe_bitmap = from->left_user_fringe_bitmap;
+      to->right_user_fringe_bitmap = from->right_user_fringe_bitmap;
+      to->left_fringe_bitmap = from->left_fringe_bitmap;
+      to->right_fringe_bitmap = from->right_fringe_bitmap;
+      to->left_user_fringe_face_id = from->left_user_fringe_face_id;
+      to->right_user_fringe_face_id = from->right_user_fringe_face_id;
+      to->left_fringe_face_id = from->left_fringe_face_id;
+      to->right_fringe_face_id = from->right_fringe_face_id;
+      to->left_fringe_offset = from->left_fringe_offset;
+      to->right_fringe_offset = from->right_fringe_offset;
+      to->fringe_bitmap_periodic_p = from->fringe_bitmap_periodic_p;
+      to->redraw_fringe_bitmaps_p = from->redraw_fringe_bitmaps_p;
+      to->enabled_p = from->enabled_p;
+      to->truncated_on_left_p = from->truncated_on_left_p;
+      to->truncated_on_right_p = from->truncated_on_right_p;
+      to->continued_p = from->continued_p;
+      to->displays_text_p = from->displays_text_p;
+      to->ends_at_zv_p = from->ends_at_zv_p;
+      to->fill_line_p = from->fill_line_p;
+      to->indicate_empty_line_p = from->indicate_empty_line_p;
+      to->contains_overlapping_glyphs_p = from->contains_overlapping_glyphs_p;
+      to->full_width_p = from->full_width_p;
+      to->mode_line_p = from->mode_line_p;
+      to->overlapped_p = from->overlapped_p;
+      to->ends_in_middle_of_char_p = from->ends_in_middle_of_char_p;
+      to->starts_in_middle_of_char_p = from->starts_in_middle_of_char_p;
+      to->overlapping_p = from->overlapping_p;
+      to->mouse_face_p = from->mouse_face_p;
+      to->ends_in_newline_from_string_p = from->ends_in_newline_from_string_p;
+      to->exact_window_width_line_p = from->exact_window_width_line_p;
+      to->cursor_in_fringe_p = from->cursor_in_fringe_p;
+      to->ends_in_ellipsis_p = from->ends_in_ellipsis_p;
+      to->indicate_bob_p = from->indicate_bob_p;
+      to->indicate_top_line_p = from->indicate_top_line_p;
+      to->indicate_eob_p = from->indicate_eob_p;
+      to->indicate_bottom_line_p = from->indicate_bottom_line_p;
+      to->reversed_p = from->reversed_p;
+      to->continuation_lines_width = from->continuation_lines_width;
+      to->clip = from->clip;
+      if (from->used[LEFT_MARGIN_AREA])
+        {
+          nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+          to->glyphs[LEFT_MARGIN_AREA] = xmalloc (nbytes);
+          memcpy (to->glyphs[LEFT_MARGIN_AREA], from->glyphs[LEFT_MARGIN_AREA], nbytes);
+          to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+        }
+      if (from->used[RIGHT_MARGIN_AREA])
+        {
+          nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+          to->glyphs[RIGHT_MARGIN_AREA] = xmalloc (nbytes);
+          memcpy (to->glyphs[RIGHT_MARGIN_AREA], from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+          to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+        }
+    }
+  return saved;
+}
+
+void
+mc_restore_glyph_matrix (struct glyph_matrix *saved, struct glyph_matrix *matrix)
+{
+  /* NOTE:  Assumes the matrix being restored already exists. */
+  // NOT RESTORED:  struct glyph_pool *pool;
+  matrix->rows_allocated = saved->rows_allocated;
+  matrix->nrows = saved->nrows;
+  matrix->matrix_x = saved->matrix_x;
+  matrix->matrix_y = saved->matrix_y;
+  matrix->matrix_w = saved->matrix_w;
+  matrix->matrix_h = saved->matrix_h;
+  matrix->window_pixel_left = saved->window_pixel_left;
+  matrix->window_pixel_top = saved->window_pixel_top;
+  matrix->window_height = saved->window_height;
+  matrix->window_width = saved->window_width;
+  matrix->window_vscroll = saved->window_vscroll;
+  matrix->left_margin_glyphs = saved->left_margin_glyphs;
+  matrix->right_margin_glyphs = saved->right_margin_glyphs;
+  matrix->no_scrolling_p = saved->no_scrolling_p;
+  matrix->header_line_p = saved->header_line_p;
+#ifdef GLYPH_DEBUG
+  // matrix->method = saved->method;
+#endif
+  // NOT RESTORED:  struct buffer *buffer;
+  matrix->begv = saved->begv;
+  matrix->zv = saved->zv;
+  for (int i = 0; i < saved->nrows; ++i)
+    {
+      struct glyph_row *from = saved->rows + i;
+      struct glyph_row *to = matrix->rows + i;
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
+      to->used[TEXT_AREA] = from->used[TEXT_AREA];
+      to->hash = from->hash;
+      to->x = from->x;
+      to->y = from->y;
+      to->pixel_width = from->pixel_width;
+      to->ascent = from->ascent;
+      to->height = from->height;
+      to->phys_ascent = from->phys_ascent;
+      to->phys_height = from->phys_height;
+      to->visible_height = from->visible_height;
+      to->extra_line_spacing = from->extra_line_spacing;
+      to->start = from->start;
+      to->end = from->end;
+      to->minpos = from->minpos;
+      to->maxpos = from->maxpos;
+      to->overlay_arrow_bitmap = from->overlay_arrow_bitmap;
+      to->left_user_fringe_bitmap = from->left_user_fringe_bitmap;
+      to->right_user_fringe_bitmap = from->right_user_fringe_bitmap;
+      to->left_fringe_bitmap = from->left_fringe_bitmap;
+      to->right_fringe_bitmap = from->right_fringe_bitmap;
+      to->left_user_fringe_face_id = from->left_user_fringe_face_id;
+      to->right_user_fringe_face_id = from->right_user_fringe_face_id;
+      to->left_fringe_face_id = from->left_fringe_face_id;
+      to->right_fringe_face_id = from->right_fringe_face_id;
+      to->left_fringe_offset = from->left_fringe_offset;
+      to->right_fringe_offset = from->right_fringe_offset;
+      to->fringe_bitmap_periodic_p = from->fringe_bitmap_periodic_p;
+      to->redraw_fringe_bitmaps_p = from->redraw_fringe_bitmaps_p;
+      to->enabled_p = from->enabled_p;
+      to->truncated_on_left_p = from->truncated_on_left_p;
+      to->truncated_on_right_p = from->truncated_on_right_p;
+      to->continued_p = from->continued_p;
+      to->displays_text_p = from->displays_text_p;
+      to->ends_at_zv_p = from->ends_at_zv_p;
+      to->fill_line_p = from->fill_line_p;
+      to->indicate_empty_line_p = from->indicate_empty_line_p;
+      to->contains_overlapping_glyphs_p = from->contains_overlapping_glyphs_p;
+      to->full_width_p = from->full_width_p;
+      to->mode_line_p = from->mode_line_p;
+      to->overlapped_p = from->overlapped_p;
+      to->ends_in_middle_of_char_p = from->ends_in_middle_of_char_p;
+      to->starts_in_middle_of_char_p = from->starts_in_middle_of_char_p;
+      to->overlapping_p = from->overlapping_p;
+      to->mouse_face_p = from->mouse_face_p;
+      to->ends_in_newline_from_string_p = from->ends_in_newline_from_string_p;
+      to->exact_window_width_line_p = from->exact_window_width_line_p;
+      to->cursor_in_fringe_p = from->cursor_in_fringe_p;
+      to->ends_in_ellipsis_p = from->ends_in_ellipsis_p;
+      to->indicate_bob_p = from->indicate_bob_p;
+      to->indicate_top_line_p = from->indicate_top_line_p;
+      to->indicate_eob_p = from->indicate_eob_p;
+      to->indicate_bottom_line_p = from->indicate_bottom_line_p;
+      to->reversed_p = from->reversed_p;
+      to->continuation_lines_width = from->continuation_lines_width;
+      to->clip = from->clip;
+      xfree (from->glyphs[TEXT_AREA]);
+      nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+        {
+          memcpy (to->glyphs[LEFT_MARGIN_AREA], from->glyphs[LEFT_MARGIN_AREA], nbytes);
+          to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+          xfree (from->glyphs[LEFT_MARGIN_AREA]);
+        }
+      else
+        to->used[LEFT_MARGIN_AREA] = 0;
+      nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+        {
+          memcpy (to->glyphs[RIGHT_MARGIN_AREA], from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+          to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+          xfree (from->glyphs[RIGHT_MARGIN_AREA]);
+        }
+      else
+        to->used[RIGHT_MARGIN_AREA] = 0;
+    }
+  xfree (saved->rows);
+  xfree (saved);
+}
+
+void
+mc_xfree_glyph_matrix (struct glyph_matrix *matrix)
+{
+  for (int i = 0; i < matrix->nrows; ++i)
+    {
+      ptrdiff_t nbytes;
+      struct glyph_row *row = matrix->rows + i;
+      nbytes = row->used[TEXT_AREA] * sizeof (struct glyph);
+      if (nbytes)
+        xfree (row->glyphs[TEXT_AREA]);
+      nbytes = row->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+        xfree (row->glyphs[LEFT_MARGIN_AREA]);
+      nbytes = row->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+      if (nbytes)
+        xfree (row->glyphs[RIGHT_MARGIN_AREA]);
+    }
+  xfree (matrix->rows);
+  xfree (matrix);
+}
+
+/* Try to reuse part of the current display of W by scrolling lines.
+   HEADER_LINE_P means W has a header line.
+   . The algorithm is taken from Communications of the ACM, Apr78 "A Technique
+     for Isolating Differences Between Files."  It should take O(N) time.
+   A short outline of the steps of the algorithm:
+     1. Skip lines equal at the start and end of both matrices.
+     2. Enter rows in the current and desired matrix into a symbol table,
+        counting how often they appear in both matrices.
+     3. Rows that appear exactly once in both matrices serve as anchors, i.e. we
+        assume that such lines are likely to have been moved.
+     4. Starting from anchor lines, extend regions to be scrolled both forward
+        and backward.
+   Value is
+     -1 if all rows were found to be equal.
+     0 to indicate that we did not scroll the display, or
+     1 if we did scroll. */
+static int
+mc_scrolling_window (struct window *w, bool header_line_p)
+{
+  struct glyph_matrix *desired_matrix = w->desired_matrix;
+  struct glyph_matrix *current_matrix = w->current_matrix;
+  int yb = window_text_bottom_y (w);
+  ptrdiff_t i;
+  int j, first_old, first_new, last_old, last_new;
+  int nruns, run_idx;
+  ptrdiff_t n;
+  struct mc_row_entry *entry;
+  // struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+  /* Skip over rows equal at the start. */
+  for (i = header_line_p; i < current_matrix->nrows - 1; ++i)
+    {
+      struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
+      struct glyph_row *c = MATRIX_ROW (current_matrix, i);
+      if (c->enabled_p
+          && d->enabled_p
+          && !d->redraw_fringe_bitmaps_p
+          && c->y == d->y
+          && MATRIX_ROW_BOTTOM_Y (c) <= yb
+          && MATRIX_ROW_BOTTOM_Y (d) <= yb
+          && row_equal_p (c, d, 1))
+        {
+          assign_row (c, d);
+          d->enabled_p = false;
+        }
+        else
+          break;
+    }
+#ifdef HAVE_XWIDGETS
+  /* Currently this seems needed to detect xwidget movement reliably. */
+    return 0;
+#endif
+  /* Give up if some rows in the desired matrix are not enabled. */
+  if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
+    return -1;
+  first_old = first_new = i;
+  /* Set last_new to the index + 1 of the row that reaches the
+     bottom boundary in the desired matrix.  Give up if we find a
+     disabled row before we reach the bottom boundary. */
+  i = first_new + 1;
+  while (i < desired_matrix->nrows - 1)
+    {
+      int bottom;
+      if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
+        return 0;
+      bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
+      if (bottom <= yb)
+        ++i;
+      if (bottom >= yb)
+        break;
+    }
+  last_new = i;
+  /* Set last_old to the index + 1 of the row that reaches the bottom
+     boundary in the current matrix.  We don't look at the enabled
+     flag here because we plan to reuse part of the display even if
+     other parts are disabled. */
+  i = first_old + 1;
+  while (i < current_matrix->nrows - 1)
+    {
+      int bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i));
+      if (bottom <= yb)
+        ++i;
+      if (bottom >= yb)
+        break;
+    }
+  last_old = i;
+  /* Skip over rows equal at the bottom. */
+  i = last_new;
+  j = last_old;
+  while (i - 1 > first_new
+         && j - 1 > first_old
+         && MATRIX_ROW_ENABLED_P (current_matrix, j - 1)
+         && (MATRIX_ROW (current_matrix, j - 1)->y
+             == MATRIX_ROW (desired_matrix, i - 1)->y)
+         && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
+         && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
+                         MATRIX_ROW (current_matrix, j - 1), 1))
+    --i, --j;
+  last_new = i;
+  last_old = j;
+  /* Nothing to do if all rows are equal. */
+  if (last_new == first_new)
+    return 0;
+  /* Check for integer overflow in size calculation.
+     If next_almost_prime checks (N) for divisibility by 2..10, then
+     it can return at most N + 10, e.g., next_almost_prime (1) == 11.
+     So, set next_almost_prime_increment_max to 10.
+     It's just a coincidence that next_almost_prime_increment_max ==
+     NEXT_ALMOST_PRIME_LIMIT - 1.  If NEXT_ALMOST_PRIME_LIMIT were
+     13, then next_almost_prime_increment_max would be 14, e.g.,
+     because next_almost_prime (113) would be 127. */
+  {
+    verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+    enum { next_almost_prime_increment_max = 10 };
+    ptrdiff_t row_table_max =
+      (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *mc_row_table)
+       - next_almost_prime_increment_max);
+    ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
+    if (current_nrows_max < current_matrix->nrows)
+      memory_full (SIZE_MAX);
+  }
+  /* Reallocate vectors, tables etc. if necessary. */
+  if (current_matrix->nrows > mc_old_lines_size)
+    mc_old_lines = xpalloc (mc_old_lines, &mc_old_lines_size,
+                         current_matrix->nrows - mc_old_lines_size,
+                         INT_MAX, sizeof *mc_old_lines);
+  if (desired_matrix->nrows > mc_new_lines_size)
+    mc_new_lines = xpalloc (mc_new_lines, &mc_new_lines_size,
+                         desired_matrix->nrows - mc_new_lines_size,
+                         INT_MAX, sizeof *mc_new_lines);
+  n = desired_matrix->nrows;
+  n += current_matrix->nrows;
+  if (mc_row_table_size < 3 * n)
+    {
+      ptrdiff_t size = next_almost_prime (3 * n);
+      mc_row_table = xnrealloc (mc_row_table, size, sizeof *mc_row_table);
+      mc_row_table_size = size;
+      memset (mc_row_table, 0, size * sizeof *mc_row_table);
+    }
+  if (n > mc_row_entry_pool_size)
+    mc_row_entry_pool = xpalloc (mc_row_entry_pool, &mc_row_entry_pool_size,
+                              n - mc_row_entry_pool_size,
+                              -1, sizeof *mc_row_entry_pool);
+  if (desired_matrix->nrows > mc_runs_size)
+    {
+      mc_runs = xnrealloc (mc_runs, desired_matrix->nrows, sizeof *mc_runs);
+      mc_run_pool = xnrealloc (mc_run_pool, desired_matrix->nrows, sizeof *mc_run_pool);
+      mc_runs_size = desired_matrix->nrows;
+    }
+  nruns = run_idx = 0;
+  mc_row_entry_idx = 0;
+  /* Add rows from the current and desired matrix to the hash table
+     row_hash_table to be able to find equal ones quickly. */
+  for (i = first_old; i < last_old; ++i)
+    {
+      if (MATRIX_ROW_ENABLED_P (current_matrix, i))
+        {
+          entry = mc_add_row_entry (MATRIX_ROW (current_matrix, i));
+          mc_old_lines[i] = entry;
+          ++entry->old_uses;
+        }
+      else
+        mc_old_lines[i] = NULL;
+    }
+  for (i = first_new; i < last_new; ++i)
+    {
+      eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
+      entry = mc_add_row_entry (MATRIX_ROW (desired_matrix, i));
+      ++entry->new_uses;
+      entry->new_line_number = i;
+      mc_new_lines[i] = entry;
+    }
+  /* Identify moves based on lines that are unique and equal
+     in both matrices. */
+  for (i = first_old; i < last_old;)
+    if (mc_old_lines[i]
+        && mc_old_lines[i]->old_uses == 1
+        && mc_old_lines[i]->new_uses == 1)
+      {
+        int p, q;
+        int new_line = mc_old_lines[i]->new_line_number;
+        struct run *run = mc_run_pool + run_idx++;
+        /* Record move. */
+        run->current_vpos = i;
+        run->current_y = MATRIX_ROW (current_matrix, i)->y;
+        run->desired_vpos = new_line;
+        run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
+        run->nrows = 1;
+        run->height = MATRIX_ROW (current_matrix, i)->height;
+        /* Extend backward. */
+        p = i - 1;
+        q = new_line - 1;
+        while (p > first_old
+               && q > first_new
+               && mc_old_lines[p] == mc_new_lines[q])
+          {
+            int h = MATRIX_ROW (current_matrix, p)->height;
+            --run->current_vpos;
+            --run->desired_vpos;
+            ++run->nrows;
+            run->height += h;
+            run->desired_y -= h;
+            run->current_y -= h;
+            --p, --q;
+          }
+        /* Extend forward. */
+        p = i + 1;
+        q = new_line + 1;
+        while (p < last_old
+               && q < last_new
+               && mc_old_lines[p] == mc_new_lines[q])
+          {
+            int h = MATRIX_ROW (current_matrix, p)->height;
+            ++run->nrows;
+            run->height += h;
+            ++p, ++q;
+          }
+        /* Insert run into list of all runs.  Order runs by copied
+           pixel lines.  Note that we record runs that don't have to
+           be copied because they are already in place.  This is done
+           because we can avoid calling update_window_line in this
+           case. */
+        for (p = 0; p < nruns && mc_runs[p]->height > run->height; ++p)
+          ;
+        for (q = nruns; q > p; --q)
+          mc_runs[q] = mc_runs[q - 1];
+        mc_runs[p] = run;
+        ++nruns;
+        i += run->nrows;
+      }
+      else
+        ++i;
+  /* Do the moves.  Do it in a way that we don't overwrite something
+     we want to copy later on.  This is not solvable in general
+     because there is only one display and we don't have a way to
+     exchange areas on this display.  Example:
+          +-----------+       +-----------+
+          |     A     |       |     B     |
+          +-----------+  -->  +-----------+
+          |     B     |       |     A     |
+          +-----------+       +-----------+
+     Instead, prefer bigger moves, and invalidate moves that would
+     copy from where we copied to. */
+  for (i = 0; i < nruns; ++i)
+    if (mc_runs[i]->nrows > 0)
+      {
+        struct run *r = mc_runs[i];
+        if (r->current_y != r->desired_y)
+          {
+            //  fprintf (stderr, "%s:  r->current/desired_vpos (%d/%d) | r->current/desired_y (%d/%d)\n",
+            //           r->current_y < r->desired_y ? "↓" : "↑",
+            //           r->current_vpos, r->desired_vpos, r->current_y, r->desired_y);
+            //  rif->clear_window_mouse_face (w);
+            //  rif->scroll_run_hook (w, r);
+          }
+        /* Truncate runs that copy to where we copied to, and
+           invalidate runs that copy from where we copied to. */
+        for (j = nruns - 1; j > i; --j)
+          {
+            struct run *p = mc_runs[j];
+            bool truncated_p = 0;
+            if (p->nrows > 0
+                && p->desired_y < r->desired_y + r->height
+                && p->desired_y + p->height > r->desired_y)
+              {
+                if (p->desired_y < r->desired_y)
+                  {
+                    p->nrows = r->desired_vpos - p->desired_vpos;
+                    p->height = r->desired_y - p->desired_y;
+                    truncated_p = 1;
+                  }
+                else
+                  {
+                    int nrows_copied = (r->desired_vpos + r->nrows
+                                        - p->desired_vpos);
+                    if (p->nrows <= nrows_copied)
+                      p->nrows = 0;
+                      else
+                        {
+                          int height_copied = (r->desired_y + r->height
+                                               - p->desired_y);
+                          p->current_vpos += nrows_copied;
+                          p->desired_vpos += nrows_copied;
+                          p->nrows -= nrows_copied;
+                          p->current_y += height_copied;
+                          p->desired_y += height_copied;
+                          p->height -= height_copied;
+                          truncated_p = 1;
+                        }
+                  }
+              }
+            if (r->current_y != r->desired_y
+                /* The condition below is equivalent to
+                   ((p->current_y >= r->desired_y
+                     && p->current_y < r->desired_y + r->height)
+                    || (p->current_y + p->height > r->desired_y
+                        && (p->current_y + p->height
+                            <= r->desired_y + r->height)))
+                   because we have 0 < p->height <= r->height. */
+                && p->current_y < r->desired_y + r->height
+                && p->current_y + p->height > r->desired_y)
+              p->nrows = 0;
+            /* Reorder runs by copied pixel lines if truncated. */
+            if (truncated_p && p->nrows > 0)
+              {
+                int k = nruns - 1;
+                while (mc_runs[k]->nrows == 0 || mc_runs[k]->height < p->height)
+                  k--;
+                memmove (mc_runs + j, mc_runs + j + 1, (k - j) * sizeof (*mc_runs));
+                mc_runs[k] = p;
+              }
+          }
+        /* Assign matrix rows. */
+        for (j = 0; j < r->nrows; ++j)
+          {
+            struct glyph_row *from, *to;
+            bool to_overlapped_p;
+            to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
+            from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
+            to_overlapped_p = to->overlapped_p;
+            from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
+            assign_row (to, from);
+            /* The above `assign_row' actually does swap, so if we had
+               an overlap in the copy destination of two runs, then
+               the second run would assign a previously disabled bogus
+               row.  But thanks to the truncation code in the
+               preceding for-loop, we no longer have such an overlap,
+               and thus the assigned row should always be enabled. */
+            eassert (to->enabled_p);
+            from->enabled_p = false;
+            to->overlapped_p = to_overlapped_p;
+          }
+      }
+  /* Clear the hash table, for the next time. */
+  for (i = 0; i < mc_row_entry_idx; ++i)
+    mc_row_table[mc_row_entry_pool[i].bucket] = NULL;
+  /* Value is 1 to indicate that we scrolled the display. */
+  return nruns > 0;
+}
+
+/* `mc_update_text_area' (cursor row):  `desired_row` / `desired_row` / `vpos`
+   `mc_update_text_area' (not cursor row):  `current_row` / `desired_row` / `vpos`
+   `mc_update_window_dryrun':  `current_row` / `current_row` / `vpos`
+   `update_window':  `current_row` / `current_row` / `vpos`
+   `mc_update_window_fringes':  `current_row` / `current_row` / `vpos`*/
+enum mc_row_position
+mc_row_position (struct window *w, struct glyph_row *current_row, struct glyph_row *desired_row, int vpos)
+{
+  int header_line_format = WINDOW_HEADER_LINE_HEIGHT (w);
+  ptrdiff_t bob_disregard_narrow = BUF_BEG (XBUFFER (w->contents));
+  ptrdiff_t eob_disregard_narrow = BUF_Z (XBUFFER (w->contents));
+  ptrdiff_t bob_respect_narrow = BUF_BEGV (XBUFFER (w->contents));
+  ptrdiff_t eob_respect_narrow = BUF_ZV (XBUFFER (w->contents));
+  ptrdiff_t buffer_size = eob_disregard_narrow - bob_disregard_narrow;
+  bool buffer_narrowed_p = (eob_respect_narrow - bob_respect_narrow != buffer_size);
+  /* Except as to the cursor row (which is processed before all other rows), we
+  rely upon the previous row in the current matrix.  As to the cursor row, we
+  reply upon the previous row in the desired matrix -- this is acceptable because
+  the pointers between desired/current row matrices have not yet been swapped by
+  `make_current' in `update_window_line', or because the previous row would be
+  the same in both matrices if we jumped to `set_cursor:` within `update_window'
+  and `mc_update_window_dryrun'. */
+  int prev_matrix_row_start_bytepos = (vpos != 0)
+                                      ? MATRIX_ROW_START_BYTEPOS (current_row - 1)
+                                      : -1;
+  int prev_matrix_row_end_bytepos = (vpos != 0)
+                                    ? MATRIX_ROW_END_BYTEPOS (current_row - 1)
+                                    : -1;
+  int matrix_row_start_bytepos = MATRIX_ROW_START_BYTEPOS (desired_row);
+  int matrix_row_end_bytepos = MATRIX_ROW_END_BYTEPOS (desired_row);
+  /* The first condition tests for a solitary row containing ZV, preceded by a
+  row containing a penultimate glyph with a charpos of ZV - 1 followed by an end
+  of row space glyph with a charpos of 0.  The other conditions test for an empty
+  buffer (not narrowed), or an empty narrowed buffer. */
+  bool row_at_zv_p = ((vpos != 0
+                       && (current_row - 1)->used[TEXT_AREA] > 0
+                       && prev_matrix_row_start_bytepos != prev_matrix_row_end_bytepos
+                       && !(current_row - 1)->ends_at_zv_p
+                       && matrix_row_start_bytepos == matrix_row_end_bytepos
+                       && desired_row->ends_at_zv_p)
+                      || (((header_line_format > 0 && vpos == 1)
+                           || (header_line_format == 0 && vpos == 0))
+                          && buffer_narrowed_p
+                          && bob_respect_narrow == eob_respect_narrow)
+                      || (((header_line_format > 0 && vpos == 1)
+                           || (header_line_format == 0 && vpos == 0))
+                          && bob_disregard_narrow == eob_disregard_narrow));
+  /* If line-numbers are active, then space glyph padding equal to its width
+  counted in HPOS are followed by a single row end space glyph.  Line number
+  padding space glyphs have a charpos of -1, whereas the end of row space glyph
+  has a charpos of 0.  If line numbers are inactive, then the row will contain
+  a solitary space glyph with a charpos of -1. */
+  bool row_beyond_zv_p = (matrix_row_start_bytepos == matrix_row_end_bytepos
+                          && !row_at_zv_p);
+  return (row_at_zv_p)
+           ? AT_ZV
+         : (row_beyond_zv_p)
+           ? POST_ZV
+         : PRE_ZV;
+}
+
+/* Update the display of the text area of row VPOS in window W.
+   Value is true if display has changed. */
+static bool
+mc_update_text_area (struct window *w, struct glyph_row *updated_row, int vpos,
+                     struct glyph_matrix *cursor_matrix,
+                     struct mc_essentials essentials, bool draw_p)
+{
+  bool debug_p = false;
+  struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
+  struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+  bool changed_p = 0;
+  struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+  enum mc_flavor glyph_flavor = NO_FLAVOR;
+  enum mc_cursor_type cursor_type = NO_CURSOR;
+  int wd = -1;
+  bool cursor_gc_p = false;
+  struct glyph_matrix *desired_matrix = w->desired_matrix;
+  if (debug_p)
+    fprintf (stderr, "mc_update_text_area (%s):  vpos (%d)\n",
+                      mc_window (w), vpos);
+  /* Inasmuch as we process the cursor row before all other rows, we can rely
+  upon the previous `desired_row` to be accurate. */
+  enum mc_row_position row_position =  mc_row_position (w, vpos == w->cursor.vpos
+                                                           ? desired_row
+                                                           : current_row,
+                                                        desired_row, vpos);
+  /* If rows are at different X or Y, or rows have different height,
+     or the current row is marked invalid, write the entire line. */
+  if (!current_row->enabled_p
+      || desired_row->y != current_row->y
+      || desired_row->ascent != current_row->ascent
+      || desired_row->phys_ascent != current_row->phys_ascent
+      || desired_row->phys_height != current_row->phys_height
+      || desired_row->visible_height != current_row->visible_height
+      || current_row->overlapped_p
+      /* This next line is necessary for correctly redrawing
+         mouse-face areas after scrolling and other operations.
+         However, it causes excessive flickering when mouse is moved
+         across the mode line.  Luckily, turning it off for the mode
+         line doesn't seem to hurt anything. -- cyd.
+         But it is still needed for the header line. -- kfs. */
+      || (current_row->mouse_face_p
+          && !(current_row->mode_line_p && vpos > 0))
+      || current_row->x != desired_row->x)
+    {
+      output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
+      if (debug_p)
+        fprintf (stderr, "WRITE ENTIRE ROW:\n\
+          vpos (%d) | char (%d/%s) | start_x: (%d) | start_hpos (%d/%d)\n",
+          vpos, desired_row->glyphs[TEXT_AREA]->u.ch,
+          mc_char_to_string (desired_row->glyphs[TEXT_AREA]->u.ch),
+          desired_row->x, 0, desired_row->used[TEXT_AREA] - 1);
+      if (desired_row->used[TEXT_AREA])
+        {
+          block_input ();
+          int len = desired_row->used[TEXT_AREA];
+          int hpos = desired_row->glyphs[TEXT_AREA] - updated_row->glyphs[TEXT_AREA];
+          w->output_cursor.x =
+            mc_draw_glyphs (w, desired_matrix, updated_row, w->output_cursor.x,
+                            TEXT_AREA, hpos, hpos + len, DRAW_NORMAL_TEXT, 0,
+                            vpos, lsl, glyph_flavor, cursor_type, wd,
+                            essentials.active_p, cursor_gc_p, MC_DRAW_GLYPH_STRING,
+                            draw_p);
+          w->output_cursor.hpos += len;
+          unblock_input ();
+        }
+      /* Clear to end of window. */
+      if (draw_p)
+        rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
+      changed_p = 1;
+      /* This erases the cursor.  We do this here because
+         noticeoverwritten_text_cursor cannot easily check this, which
+         might indicate that the whole functionality of
+         noticeoverwritten_text_cursor would better be implemented here.
+         On the other hand, we need noticeoverwritten_text_cursor as long
+         as mouse highlighting is done asynchronously outside of
+         redisplay. */
+      if (vpos == w->phys_cursor.vpos)
+        w->phys_cursor_on_p = 0;
+      /* The entire row was redrawn above, so all fake cursors must be redrawn. */
+      mc_draw_row (w, desired_matrix, updated_row, desired_row->glyphs[TEXT_AREA],
+                   desired_row->x, desired_row->used[TEXT_AREA], vpos,
+                   cursor_matrix, essentials, row_position, draw_p, SCRIBE_ONE);
+    }
+    else
+      {
+        int stop, i, x;
+        struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
+        struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
+        bool overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
+        int desired_stop_pos = desired_row->used[TEXT_AREA];
+        bool abort_skipping = 0;
+        /* If the desired row extends its face to the text area end, and unless the
+        current row also does so at the same position, make sure we write at least one
+        glyph, so that the face extension actually takes place. */
+        if (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
+            && (desired_stop_pos < current_row->used[TEXT_AREA]
+                || (desired_stop_pos == current_row->used[TEXT_AREA]
+                    && !MATRIX_ROW_EXTENDS_FACE_P (current_row))))
+          --desired_stop_pos;
+        stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
+        i = 0;
+        x = desired_row->x;
+        int clear_to_x = 0;
+
+        /* Loop over glyphs that current and desired row may have in common. */
+        while (i < stop)
+          {
+            array_glyphs_skipped.used = 0;
+            bool can_skip_p = !abort_skipping;
+            /* Skip over glyphs that both rows have in common.  These don't have
+            to be written.  We can't skip if the last current glyph overlaps the
+            glyph to its right.  For example, consider a current row of `if' with
+            the `f' in Courier bold so that it overlaps the ` ' to its right.
+            If the desired row is ` ', we would skip over the space after the
+            `if' and there would remain a pixel from the `f' on the screen. */
+            if (overlapping_glyphs_p && i > 0)
+              {
+                struct glyph *glyph = &current_row->glyphs[TEXT_AREA][i - 1];
+                int left, right;
+                rif->get_glyph_overhangs (glyph, XFRAME (w->frame), &left, &right);
+                can_skip_p = (right == 0 && !abort_skipping);
+              }
+            if (can_skip_p)
+              {
+                int start_hpos = i;
+                while (i < stop
+                       && GLYPH_EQUAL_P (desired_glyph, current_glyph))
+                  {
+                    ++array_glyphs_skipped.used;
+                    if (array_glyphs_skipped.allocated < array_glyphs_skipped.used)
+                      {
+                        int old_alloc = array_glyphs_skipped.allocated;
+                        int new_elts = array_glyphs_skipped.used - array_glyphs_skipped.allocated;
+                        array_glyphs_skipped.skipped =
+                          xpalloc (array_glyphs_skipped.skipped,
+                                   &array_glyphs_skipped.allocated,
+                                   new_elts,
+                                   INT_MAX,
+                                   sizeof *array_glyphs_skipped.skipped);
+                        memset (array_glyphs_skipped.skipped + old_alloc, 0,
+                                 (array_glyphs_skipped.allocated - old_alloc)
+                                   * sizeof *array_glyphs_skipped.skipped);
+                      }
+                    int nth = array_glyphs_skipped.used - 1;
+                    array_glyphs_skipped.skipped[nth].x = x;
+                    array_glyphs_skipped.skipped[nth].hpos = i;
+                    array_glyphs_skipped.skipped[nth].enabled_p = true;
+                    x += desired_glyph->pixel_width;
+                    ++desired_glyph, ++current_glyph, ++i;
+                  }
+                /* Consider the case that the current row contains "xxx ppp ggg" in
+                italic Courier font, and the desired row is "xxx ggg".  The character `p'
+                has lbearing, `g' has not.  The loop above will stop in front of the
+                first `p' in the current row.  If we would start writing glyphs there, we
+                wouldn't erase the lbearing of the `p'.  The rest of the lbearing problem
+                is then taken care of by draw_glyphs. */
+                if (overlapping_glyphs_p
+                    && i > 0
+                    && i < current_row->used[TEXT_AREA]
+                    && (current_row->used[TEXT_AREA] != desired_row->used[TEXT_AREA]))
+                  {
+                    int left, right;
+                    rif->get_glyph_overhangs (current_glyph,
+                            XFRAME (w->frame),
+                            &left, &right);
+                    while (left > 0 && i > 0)
+                      {
+                        --i, --desired_glyph, --current_glyph;
+                        x -= desired_glyph->pixel_width;
+                        left -= desired_glyph->pixel_width;
+                      }
+                    /* Abort the skipping algorithm if we end up before
+                       our starting point, to avoid looping (bug#1070).
+                       This can happen when the lbearing is larger than
+                       the pixel width. */
+                    abort_skipping = (i < start_hpos);
+                  }
+              }
+            /* Try to avoid writing the entire rest of the desired row
+               by looking for a resync point.  This mainly prevents
+               mode line flickering in the case the mode line is in
+               fixed-pitch font, which it usually will be. */
+            if (i < desired_row->used[TEXT_AREA])
+              {
+                int start_x = x, start_hpos = i;
+                struct glyph *start = desired_glyph;
+                int current_x = x;
+                bool skip_first_p = !can_skip_p;
+                /* Find the next glyph that's equal again. */
+                while (i < stop
+                       && (skip_first_p
+                           || !GLYPH_EQUAL_P (desired_glyph, current_glyph))
+                       && x == current_x)
+                  {
+                    x += desired_glyph->pixel_width;
+                    current_x += current_glyph->pixel_width;
+                    ++desired_glyph, ++current_glyph, ++i;
+                    skip_first_p = 0;
+                  }
+                for (int elt = 0;
+                     elt < array_glyphs_skipped.used;
+                     ++elt)
+                  {
+                    int x = array_glyphs_skipped.skipped[elt].x;
+                    int hpos = array_glyphs_skipped.skipped[elt].hpos;
+                    struct glyph *target_glyph =
+                      mc_get_cursor_glyph (w, desired_matrix, updated_row, hpos, vpos);
+                    if (debug_p)
+                      fprintf (stderr, "SKIPPED:  vpos (%d) | char (%d/%s) | x: (%d) | hpos (%d/%d)\n",
+                                       vpos, target_glyph->u.ch,
+                                       mc_char_to_string (target_glyph->u.ch),
+                                       x, hpos, updated_row->used[TEXT_AREA] - 1);
+                    mc_draw_row (w, desired_matrix, updated_row, target_glyph, x, 1, vpos,
+                                 cursor_matrix, essentials, row_position, draw_p, SKIPPED);
+                  }
+                if (i == start_hpos || x != current_x)
+                  {
+                    i = start_hpos;
+                    x = start_x;
+                    desired_glyph = start;
+                    break;
+                  }
+                output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
+                /* Re-draw a portion of the row. */
+                if (debug_p)
+                  fprintf (stderr, "REDRAW SEGMENT:\n\
+                    vpos (%d) | char (%d/%s) | x: (%d) | hpos (%d/%d) | length (%d)\n",
+                    vpos, start->u.ch, mc_char_to_string (start->u.ch),
+                    start_x, start_hpos, updated_row->used[TEXT_AREA] - 1, i - start_hpos);
+                block_input ();
+                int len = i - start_hpos;
+                int hpos = start - updated_row->glyphs[TEXT_AREA];
+                w->output_cursor.x =
+                  mc_draw_glyphs (w, desired_matrix, updated_row, w->output_cursor.x,
+                                  TEXT_AREA, hpos, hpos + len, DRAW_NORMAL_TEXT,
+                                  0, vpos, lsl, glyph_flavor, cursor_type, wd,
+                                  essentials.active_p, cursor_gc_p, MC_DRAW_GLYPH_STRING,
+                                  draw_p);
+                w->output_cursor.hpos += len;
+                unblock_input ();
+                mc_draw_row (w, desired_matrix, updated_row, start, start_x, i - start_hpos,
+                             vpos, cursor_matrix, essentials, row_position, draw_p, SCRIBE_TWO);
+                changed_p = 1;
+              }
+          }
+
+        /* Write the rest. */
+        if (i < desired_row->used[TEXT_AREA])
+          {
+            output_cursor_to (w, vpos, i, desired_row->y, x);
+            if (debug_p)
+              fprintf (stderr, "DRAW REMAINDER OF THE ROW:\n\
+                vpos (%d) | char (%d/%s) | x: (%d) | hpos (%d/%d) | length (%d)\n",
+                vpos, desired_glyph->u.ch, mc_char_to_string (desired_glyph->u.ch),
+                x, i, desired_row->used[TEXT_AREA] - 1, desired_row->used[TEXT_AREA] - i);
+            block_input ();
+            int len = desired_row->used[TEXT_AREA] - i;
+            int hpos = desired_glyph - updated_row->glyphs[TEXT_AREA];
+            w->output_cursor.x =
+              mc_draw_glyphs (w, desired_matrix, updated_row, w->output_cursor.x,
+                              TEXT_AREA, hpos, hpos + len, DRAW_NORMAL_TEXT, 0,
+                              vpos, lsl, glyph_flavor, cursor_type, wd,
+                              essentials.active_p, cursor_gc_p, MC_DRAW_GLYPH_STRING,
+                              draw_p);
+            w->output_cursor.hpos += len;
+            unblock_input ();
+            /* FIXME:  Although we need to update the cache between the end of
+            updated_row and the right window edge, it is not necessary to draw
+            those fake cursors. Although we may not be able to see it with the
+            naked eye, those fake cursors are being superimposed on the existing
+            fake cursors that do not get erased by the code in the section below.
+            It would be better to only update the cache and suppress double-drawing
+            the fake cursors for the aforementioned area at issue. */
+            mc_draw_row (w, desired_matrix, updated_row, desired_glyph, x,
+                         desired_row->used[TEXT_AREA] - i, vpos, cursor_matrix,
+                         essentials, row_position, draw_p, SCRIBE_THREE);
+            changed_p = 1;
+          }
+          /* Everything after the previous change remained the same.  `i` and `x` were
+          incremented to the end of the glyph row.  i == desired_row->used[TEXT_AREA]
+          The `w->output_cursor.x/y/hpos/vpos` is at the end of the previous change.
+          When this situation exists, the distance between the end of the glyph row and
+          the right edge of the window will _not_ be cleared.  Therefore, it is okay to
+          draw the floating glyphs for the horizontal/vertical rulers here. */
+          else if (changed_p
+                   && w->output_cursor.hpos != updated_row->used[TEXT_AREA])
+            {
+              int x = w->output_cursor.x;
+              int hpos = w->output_cursor.hpos;
+              struct glyph *start = mc_get_cursor_glyph (w, desired_matrix,
+                                                         updated_row, hpos, vpos);
+              if (w->output_cursor.x == updated_row->pixel_width)
+                x -= start->pixel_width;
+              if (debug_p)
+                fprintf (stderr, "POST-CHANGED:  vpos (%d) | x (%d) | hpos (%d/%d) | char (%d/%s)\n",
+                                 vpos, x, hpos, updated_row->used[TEXT_AREA] - 1,
+                                 start->u.ch, mc_char_to_string (start->u.ch));
+              mc_draw_row (w, desired_matrix, updated_row, start, x,
+                           updated_row->used[TEXT_AREA] - hpos, vpos, cursor_matrix,
+                           essentials, row_position, draw_p, POST_CHANGED);
+            }
+            /* There were no changes and i == desired_row->used[TEXT_AREA] */
+            else if (!changed_p)
+              {
+                if (debug_p)
+                  fprintf (stderr, "UNCHANGED -- WRITE ENTIRE LINE:  vpos (%d) | row->used (%d)\n",
+                                   vpos, updated_row->used[TEXT_AREA] - 1);
+                mc_draw_row (w, desired_matrix, updated_row, desired_row->glyphs[TEXT_AREA],
+                             desired_row->x, desired_row->used[TEXT_AREA], vpos,
+                             cursor_matrix, essentials, row_position, draw_p, UNCHANGED);
+              }
+
+        /* Maybe clear to end of line. */
+        if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
+          {
+            /* If new row extends to the end of the text area, nothing
+               has to be cleared, if and only if we did a write_glyphs
+               above.  This is made sure by setting desired_stop_pos
+               appropriately above. */
+            eassert (i < desired_row->used[TEXT_AREA]
+                     || ((desired_row->used[TEXT_AREA] == current_row->used[TEXT_AREA])
+                         && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
+          }
+          else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
+            {
+              /* If old row extends to the end of the text area, clear. */
+              if (i >= desired_row->used[TEXT_AREA])
+                output_cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width);
+              if (draw_p)
+                rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
+              clear_to_x = -1;
+              changed_p = 1;
+            }
+            else if (desired_row->pixel_width < current_row->pixel_width)
+              {
+                /* Otherwise clear to the end of the old row.  Everything
+                   after that position should be clear already. */
+                int xlim;
+                if (i >= desired_row->used[TEXT_AREA])
+                  output_cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width);
+                /* If cursor is displayed at the end of the line, make sure
+                   it's cleared.  Nowadays we don't have a phys_cursor_glyph
+                   with which to erase the cursor (because this method
+                   doesn't work with lbearing/rbearing), so we must do it this way. */
+                if (vpos == w->phys_cursor.vpos
+                    && (desired_row->reversed_p
+                        ? (w->phys_cursor.hpos < 0)
+                        : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
+                  {
+                    w->phys_cursor_on_p = 0;
+                    xlim = -1;
+                  }
+                  else
+                    xlim = current_row->pixel_width;
+                if (draw_p)
+                  rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
+                clear_to_x = xlim;
+                changed_p = 1;
+              }
+
+        if (changed_p
+            && clear_to_x != 0)
+          {
+            int text_area_width = window_box_width (w, TEXT_AREA);
+            struct mc_RGB debug_fg = {.red = 0.867, .green = 0.867, .blue = 0.867};
+            struct glyph *target_glyph =
+              updated_row->glyphs[TEXT_AREA] + updated_row->used[TEXT_AREA] - 1;
+            /* `mc_engine' only draws an MC_GLYPH when x < updated_row->pixel_width.
+            The current design inhibits drawing over an existing glyph at the end of a
+            word-wrapped line.  Said glyph receives a fake cursor in either one of the
+            previous sections above, and should not be overwritten with another one.
+            This design is needed because a word-wrapped line does not receive an extra
+            space like non-word-wrapped lines do. */
+            int x = updated_row->pixel_width;
+            int hpos = updated_row->used[TEXT_AREA] - 1;
+            int x_limit = (clear_to_x == -1)
+                          ? text_area_width
+                          : clear_to_x;
+            Lisp_Object buf = w->contents;
+            CHECK_BUFFER (buf);
+            struct buffer *b = XBUFFER (buf);
+            bool fill_column_trumps_p = (!NILP (BVAR (b, ch_vertical_ruler))
+                                         && !NILP (BVAR (b, fc_visible))
+                                         && w->cursor.x == essentials.fc_x);
+            if (trace_redisplay_p)
+              fprintf (stderr, "mc_update_text_area (floating):  vpos (%d) | x_limit (%d)\n",
+                               vpos, x_limit);
+            if (BUFFERP (w->contents)
+                && !NILP (BVAR (b, fc_visible))
+                && (essentials.active_p
+                    || (!essentials.active_p
+                        && !NILP (BVAR (b, fc_inactive_windows))))
+                && x < text_area_width
+                && essentials.fc_x >= x
+                && target_glyph != NULL
+                && draw_p)
+              mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA,
+                         x, x_limit, updated_row->y, hpos, vpos, MC_BAR, 1,
+                         cursor_matrix, essentials, row_position,
+                         debug_p ? debug_fg : essentials.fc_fg[row_position],
+                         FILL_COLUMN, draw_p, NOWHERE, NO_CACHE);
+            if (BUFFERP (w->contents)
+                && !NILP (BVAR (b, crosshairs))
+                && !NILP (BVAR (b, ch_horizontal_ruler))
+                && (essentials.active_p
+                    || (!essentials.active_p
+                        && !NILP (BVAR (b, ch_inactive_windows))))
+                && x < text_area_width
+                && vpos == w->cursor.vpos
+                && target_glyph != NULL
+                && draw_p)
+              mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA,
+                         x, x_limit, updated_row->y, hpos, vpos, MC_HBAR, 1,
+                         cursor_matrix, essentials, row_position,
+                         debug_p ? debug_fg : essentials.ch_fg[row_position],
+                         HORIZONTAL_RULER, draw_p, NOWHERE, NO_CACHE);
+            if (BUFFERP (w->contents)
+                && !NILP (BVAR (b, crosshairs))
+                && !NILP (BVAR (b, ch_vertical_ruler))
+                && (essentials.active_p
+                    || (!essentials.active_p
+                        && !NILP (BVAR (b, ch_inactive_windows))))
+                && !fill_column_trumps_p
+                && x < text_area_width
+                && vpos != w->cursor.vpos
+                && w->cursor.x >= x
+                && target_glyph != NULL
+                && draw_p)
+              mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA,
+                         x, x_limit, updated_row->y, hpos, vpos, MC_BAR, 1,
+                         cursor_matrix, essentials, row_position,
+                         debug_p ? debug_fg : essentials.ch_fg[row_position],
+                         VERTICAL_RULER, draw_p, NOWHERE, NO_CACHE);
+          }
+
+      }
+  return changed_p;
+}
+
+/* Update row VPOS in window W.  Value is true if display has been changed. */
+static bool
+mc_update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p,
+                       struct glyph_matrix *cursor_matrix,
+                       struct mc_essentials essentials, bool draw_p)
+{
+  struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
+  struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
+  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+  bool changed_p = 0;
+  /* A row can be completely invisible in case a desired matrix was
+     built with a vscroll and then make_cursor_line_fully_visible shifts
+     the matrix.  Make sure to make such rows current anyway, since
+     we need the correct y-position, for example, in the current matrix. */
+  if (desired_row->mode_line_p
+      || desired_row->visible_height > 0)
+    {
+      eassert (desired_row->enabled_p);
+      /* Update display of the left margin area, if there is one. */
+      if (!desired_row->full_width_p && w->left_margin_cols > 0)
+        {
+          changed_p = 1;
+          update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
+          /* Setting this flag will ensure the vertical border, if
+             any, between this window and the one on its left will be
+             redrawn.  This is necessary because updating the left
+             margin area can potentially draw over the border. */
+          current_row->redraw_fringe_bitmaps_p = 1;
+        }
+      bool updated_p = mc_update_text_area (w, desired_row, vpos, cursor_matrix,
+                                            essentials, draw_p);
+      /* Update the display of the text area. */
+      if (updated_p)
+        {
+          changed_p = 1;
+          if (current_row->mouse_face_p)
+            *mouse_face_overwritten_p = 1;
+        }
+      /* Update display of the right margin area, if there is one. */
+      if (!desired_row->full_width_p && w->right_margin_cols > 0)
+        {
+          changed_p = 1;
+          update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
+        }
+      /* Draw truncation marks etc. */
+      if (!current_row->enabled_p
+          || desired_row->y != current_row->y
+          || desired_row->visible_height != current_row->visible_height
+          || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
+          || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
+          || current_row->redraw_fringe_bitmaps_p
+          || desired_row->mode_line_p != current_row->mode_line_p
+          || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
+          || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
+              != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
+        rif->after_update_window_line_hook (w, desired_row);
+    }
+  /* Update current_row from desired_row. */
+  make_current (w->desired_matrix, w->current_matrix, vpos);
+  return changed_p;
+}
+
+void
+mc_update_window_erase (struct window *w, struct mc_matrix old_matrix)
+{
+  bool go_one_p = (old_matrix.cursors_used[MC_CACHE] > 0
+                   || old_matrix.cursors_used[CH_CACHE] > 0
+                   || old_matrix.cursors_used[FC_CACHE] > 0);
+  bool go_two_p = (BUFFERP (w->contents)
+                   && (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                       || !NILP (BVAR (XBUFFER (w->contents), fc_visible))
+                       || !NILP (BVAR (XBUFFER (w->contents), mc_conf))));
+  bool updating_frame_p = false;
+  struct frame *f = XFRAME (w->frame);
+  if (XFRAME (w->frame) != f->mc_updating_frame
+      && (go_one_p || go_two_p))
+    {
+      updating_frame_p = true;
+      update_begin (f);
+    }
+  if (w->phys_cursor_on_p
+      && go_two_p)
+    erase_phys_cursor (w);
+  for (int vnth = 0;
+       go_one_p
+       && vnth < w->mc_matrix.vpos_used;
+       ++vnth)
+    {
+      for (enum mc_cache_type cache_type = MC_CACHE;
+           cache_type < NO_CACHE;
+           ++cache_type)
+        for (int nth_0 = 0;
+             mc_traverse_cache_p (old_matrix, cache_type, vnth, nth_0);
+             ++nth_0)
+          {
+            bool same_p = false;
+            for (int w_nth = 0; w_nth < w->mc_matrix.vpos[vnth].cache_used[cache_type]; ++w_nth)
+              {
+                same_p |= (old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.type
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.type
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.bytepos
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.bytepos
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.charpos
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.charpos
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.u.val
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.u.val
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.face_id
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.face_id
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.padding_p
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.padding_p
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.left_box_line_p
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.left_box_line_p
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.right_box_line_p
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.right_box_line_p
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.voffset
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.voffset
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.pixel_width
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.pixel_width
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.slice.img.x
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.slice.img.x
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.slice.img.y
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.slice.img.y
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.slice.img.width
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.slice.img.width
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.slice.img.height
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.slice.img.height
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.slice.cmp.from
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.slice.cmp.from
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].x
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].x
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].fx
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].fx
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].y
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].y
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].fy
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].fy
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].hpos
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].hpos
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].vpos
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].vpos
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].wd
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].wd
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].h
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].h
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_type
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].cursor_type
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_width
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].cursor_width
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.red
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].fg.red
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.green
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].fg.green
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.blue
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].fg.blue
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.red
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].bg.red
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.green
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].bg.green
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.blue
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].bg.blue
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].active_p
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].active_p
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph_flavor
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph_flavor
+                           && old_matrix.vpos[vnth].cache[cache_type][nth_0].enabled_p
+                             == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].enabled_p);
+                /* Force the fringe bitmaps to always be reset/redrawn. */
+                if (old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_type
+                      == w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].cursor_type
+                    && (old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_type == MC_LEFT_FRINGE_BITMAP
+                        || old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_type == MC_RIGHT_FRINGE_BITMAP))
+                  same_p = false;
+                if (same_p)
+                  {
+                    //  fprintf (stderr, "HIT (%s):  vpos (%d) | hpos (%d) | char (%s)\n",
+                    //                   (cache_type == MC_CACHE)
+                    //                     ? "MC"
+                    //                   : (cache_type == CH_CACHE)
+                    //                     ? "CH"
+                    //                   : (cache_type == FC_CACHE)
+                    //                     ? "FC"
+                    //                   : "NO",
+                    //                   w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].vpos,
+                    //                   w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].hpos,
+                    //                   mc_char_to_string (w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.u.ch));
+                    w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].same_p = true;
+                    break;
+                  }
+                  else
+                    {
+                      //  fprintf (stderr, "MISS (%s):  vpos (%d) | hpos (%d v. %d) | char (%s v. %s) | cache_used (%d v. %d)\n",
+                      //                   (cache_type == MC_CACHE)
+                      //                     ? "MC"
+                      //                   : (cache_type == CH_CACHE)
+                      //                     ? "CH"
+                      //                   : (cache_type == FC_CACHE)
+                      //                     ? "FC"
+                      //                   : "NO",
+                      //                   w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].vpos,
+                      //                   old_matrix.vpos[vnth].cache[cache_type][nth_0].hpos,
+                      //                   w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].hpos,
+                      //                   mc_char_to_string (old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph.u.ch),
+                      //                   mc_char_to_string (w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].glyph.u.ch),
+                      //                   old_matrix.vpos[vnth].cache_used[cache_type],
+                      //                   w->mc_matrix.vpos[vnth].cache_used[cache_type]);
+                      w->mc_matrix.vpos[vnth].cache[cache_type][w_nth].same_p = false;
+                    }
+              }
+            if (!same_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)
+                  continue;
+                bool barf_crash_two = (vnth >= 0 && vnth < w->current_matrix->nrows) ? false : true;
+                if (barf_crash_two)
+                  continue;
+                struct glyph_row *vnth_row = MATRIX_ROW (w->current_matrix, vnth);
+                int x_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].x;
+                int fx_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].fx;
+                int y_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].y;
+                int fy_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].fy;
+                int hpos_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].hpos;
+                int vpos_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].vpos;
+                int wd_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].wd;
+                int h_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].h;
+                enum mc_cursor_type cursor_type_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_type;
+                int cursor_width_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].cursor_width;
+                //  struct mc_RGB lsl_fg_0 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.red,
+                //                            .green = old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.green,
+                //                            .blue = old_matrix.vpos[vnth].cache[cache_type][nth_0].fg.blue};
+                struct mc_RGB lsl_bg_0 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.red,
+                                          .green = old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.green,
+                                          .blue = old_matrix.vpos[vnth].cache[cache_type][nth_0].bg.blue};
+                bool active_p_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].active_p;
+                enum mc_flavor glyph_flavor_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].glyph_flavor;
+                bool enabled_p_0 = old_matrix.vpos[vnth].cache[cache_type][nth_0].enabled_p;
+                if (vpos_0 == vnth
+                    && glyph_flavor_0 == MC_GLYPH
+                    && enabled_p_0
+                    && vnth_row->enabled_p)
+                  {
+                    mc_erase_cursor (w, w->current_matrix, vnth_row, x_0, y_0,
+                                     hpos_0, vpos_0, glyph_flavor_0,
+                                     cursor_type_0, wd_0);
+                    old_matrix.vpos[vnth].cache[cache_type][nth_0].enabled_p = false;
+                    --old_matrix.cursors_used[cache_type];
+                    /* If we inadvertently erased another fake cursor at the same
+                    HPOS that is still enabled_p in the `old_matrix`, then redraw it. */
+                    for (enum mc_cache_type cache_type = MC_CACHE;
+                         cache_type < NO_CACHE;
+                         ++cache_type)
+                      {
+                        for (int nth_1 = 0;
+                             mc_traverse_cache_p (old_matrix, cache_type, vnth, nth_1);
+                             ++nth_1)
+                          {
+                            int x_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].x;
+                            int fx_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].fx;
+                            int y_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].y;
+                            int fy_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].fy;
+                            int hpos_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].hpos;
+                            int vpos_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].vpos;
+                            int wd_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].wd;
+                            int h_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].h;
+                            enum mc_cursor_type cursor_type_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].cursor_type;
+                            int cursor_width_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].cursor_width;
+                            struct mc_RGB lsl_fg_1 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_1].fg.red,
+                                                      .green = old_matrix.vpos[vnth].cache[cache_type][nth_1].fg.green,
+                                                      .blue = old_matrix.vpos[vnth].cache[cache_type][nth_1].fg.blue};
+                            //  struct mc_RGB lsl_bg_1 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_1].bg.red,
+                            //                            .green = old_matrix.vpos[vnth].cache[cache_type][nth_1].bg.green,
+                            //                            .blue = old_matrix.vpos[vnth].cache[cache_type][nth_1].bg.blue};
+                            bool active_p_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].active_p;
+                            enum mc_flavor glyph_flavor_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].glyph_flavor;
+                            bool enabled_p_1 = old_matrix.vpos[vnth].cache[cache_type][nth_1].enabled_p;
+                            bool go_p_1 = (hpos_0 == hpos_1
+                                           && enabled_p_1);
+                            if (!go_p_1)
+                              continue;
+                            bool remove_p_1 = false;
+                            mc_draw_erase_hybrid (w, w->current_matrix, vnth_row, x_1,
+                                                  fx_1, y_1, fy_1, hpos_1, vpos_1,
+                                                  wd_1, h_1, cursor_type_1,
+                                                  cursor_width_1, lsl_fg_1,
+                                                  active_p_1, glyph_flavor_1,
+                                                  remove_p_1);
+                          }
+                      }
+                  }
+                  else if (vpos_0 == vnth
+                           && enabled_p_0
+                           && vnth_row->enabled_p)
+                    {
+                      bool remove_p_0 = true;
+                      mc_draw_erase_hybrid (w, w->current_matrix, vnth_row, x_0,
+                                            fx_0, y_0, fy_0, hpos_0, vpos_0, wd_0,
+                                            h_0, cursor_type_0, cursor_width_0,
+                                            lsl_bg_0, active_p_0, glyph_flavor_0,
+                                            remove_p_0);
+                      old_matrix.vpos[vnth].cache[cache_type][nth_0].enabled_p = false;
+                      --old_matrix.cursors_used[cache_type];
+                      /* If we inadvertently erased another fake cursor at the same
+                      HPOS that is still enabled_p in the `old_matrix`, then redraw it. */
+                      for (enum mc_cache_type cache_type = MC_CACHE;
+                           cache_type < NO_CACHE;
+                           ++cache_type)
+                        {
+                          for (int nth_2 = 0;
+                               mc_traverse_cache_p (old_matrix, cache_type, vnth, nth_2);
+                               ++nth_2)
+                            {
+                              int x_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].x;
+                              int fx_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].fx;
+                              int y_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].y;
+                              int fy_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].fy;
+                              int hpos_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].hpos;
+                              int vpos_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].vpos;
+                              int wd_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].wd;
+                              int h_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].h;
+                              enum mc_cursor_type cursor_type_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].cursor_type;
+                              int cursor_width_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].cursor_width;
+                              struct mc_RGB lsl_fg_2 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_2].fg.red,
+                                                        .green = old_matrix.vpos[vnth].cache[cache_type][nth_2].fg.green,
+                                                        .blue = old_matrix.vpos[vnth].cache[cache_type][nth_2].fg.blue};
+                              //  struct mc_RGB lsl_bg_2 = {.red = old_matrix.vpos[vnth].cache[cache_type][nth_2].bg.red,
+                              //                            .green = old_matrix.vpos[vnth].cache[cache_type][nth_2].bg.green,
+                              //                            .blue = old_matrix.vpos[vnth].cache[cache_type][nth_2].bg.blue};
+                              bool active_p_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].active_p;
+                              enum mc_flavor glyph_flavor_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].glyph_flavor;
+                              bool enabled_p_2 = old_matrix.vpos[vnth].cache[cache_type][nth_2].enabled_p;
+                              bool go_p_2 = (hpos_0 == hpos_2
+                                             && fx_0 <= fx_2
+                                             && fx_0 + wd_0 > fx_2 + wd_2
+                                             && enabled_p_2);
+                              if (!go_p_2)
+                                continue;
+                              bool remove_p_2 = false;
+                              mc_draw_erase_hybrid (w, w->current_matrix, vnth_row, x_2,
+                                                    fx_2, y_2, fy_2, hpos_2, vpos_2,
+                                                    wd_2, h_2, cursor_type_2,
+                                                    cursor_width_2, lsl_fg_2,
+                                                    active_p_2, glyph_flavor_2,
+                                                    remove_p_2);
+                            }
+                        }
+                    }
+              }
+            }
+    }
+  if (updating_frame_p)
+    update_end (f);
+}
+
+void
+mc_update_window_dryrun (struct window *w, bool force_p, struct mc_essentials essentials)
+{
+  if (!BUFFERP (w->contents))
+    return;
+
+  if (w->mc_matrix.cursors_used[MC_CACHE] == 0
+      && w->mc_matrix.cursors_used[CH_CACHE] == 0
+      && w->mc_matrix.cursors_used[FC_CACHE] == 0
+      && NILP (BVAR (XBUFFER (w->contents), mc_conf))
+      && NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && NILP (BVAR (XBUFFER (w->contents), fc_visible)))
+    return;
+
+  // clock_t clock_start = clock();
+
+  bool draw_p = false;
+
+  struct glyph_matrix *saved_desired = mc_save_glyph_matrix (w->desired_matrix);
+  struct glyph_matrix *saved_current = mc_save_glyph_matrix (w->current_matrix);
+
+  struct mc_matrix old_matrix = mc_save_cache_matrix (w->mc_matrix);
+
+  mc_reset_cache (w);
+
+  struct glyph_matrix *cursor_matrix = NULL;
+
+  struct glyph_matrix *desired_matrix = w->desired_matrix;
+  bool paused_p;
+  int preempt_count = baud_rate / 2400 + 1;
+
+#ifdef GLYPH_DEBUG
+  /* Check that W's frame doesn't have glyph matrices. */
+  eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
+#endif
+
+  /* Check pending input the first time so that we can quickly return. */
+  if (!force_p)
+    detect_input_pending_ignore_squeezables ();
+
+  /* If forced to complete the update, or if no input is pending, do the update. */
+  if (force_p || !input_pending || !NILP (do_mouse_tracking))
+    {
+      struct glyph_row *header_line_row;
+      bool changed_p = 0;
+      bool mouse_face_overwritten_p = 0;
+      int n_updated = 0;
+      //  struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
+      //  rif->update_window_begin_hook (w);
+      int yb = window_text_bottom_y (w);
+      struct glyph_row *row = MATRIX_ROW (desired_matrix, 0);
+      struct glyph_row *end = MATRIX_MODE_LINE_ROW (desired_matrix);
+
+      /* Take note of the header line, if there is one.  We will
+         update it below, after updating all of the window's lines. */
+      if (row->mode_line_p)
+        {
+          header_line_row = row;
+          ++row;
+        }
+        else
+          header_line_row = NULL;
+
+      /* Update the mode line, if necessary. */
+      struct glyph_row *mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
+      if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
+        {
+          mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
+          update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
+                                                  desired_matrix),
+                              &mouse_face_overwritten_p);
+        }
+
+      /* Find first enabled row.  Optimizations in redisplay_internal
+         may lead to an update with only one row enabled.  There may
+         be also completely empty matrices. */
+      while (row < end && !row->enabled_p)
+        ++row;
+
+      /* Try reusing part of the display by copying. */
+      if (row < end && !w->desired_matrix->no_scrolling_p)
+        {
+          int rc = mc_scrolling_window (w, header_line_row != NULL);
+          if (rc < 0)
+            {
+              /* All rows were found to be equal. */
+              paused_p = 0;
+              goto set_cursor;
+            }
+            else if (rc > 0)
+              {
+                /* We've scrolled the display. */
+                force_p = 1;
+                changed_p = 1;
+              }
+        }
+      /* Process the cursor row at the outset if it is within `desired_matrix`.
+      When processing all other rows, we will query the `w->current_matrix` for data
+      relating to the cursor row.  `make_current` (within `update_window_line')
+      updates the `w->current_matrix` for the applicable row.  In doing so, however,
+      the applicable row in the desired matrix is altered such that we can no longer
+      rely upon the accuracy of `ROW->used[TEXT_AREA]`.  Therefore, we must now rely
+      exclusively upon `w->current_matrix' for cursor row based decisions. */
+      for (struct glyph_row *mc_row = row;
+           mc_row < end && (force_p || !input_pending);
+           ++mc_row)
+        {
+          int vpos = MATRIX_ROW_VPOS (mc_row, w->desired_matrix);
+          if (mc_row->enabled_p
+              && vpos == w->cursor.vpos)
+            {
+              cursor_matrix = w->desired_matrix;
+              if (!force_p && ++n_updated % preempt_count == 0)
+                detect_input_pending_ignore_squeezables ();
+              changed_p |= mc_update_window_line (w, vpos, &mouse_face_overwritten_p,
+                                                  cursor_matrix, essentials, draw_p);
+              if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
+                for (int i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
+                  SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
+              break;
+            }
+        }
+      cursor_matrix = w->current_matrix;
+      /* Update the rest of the lines. */
+      for (; row < end && (force_p || !input_pending); ++row)
+        /* scrolling_window resets the enabled_p flag of the rows it reuses from
+        current_matrix. */
+        if (row->enabled_p)
+          {
+            int vpos = MATRIX_ROW_VPOS (row, w->desired_matrix);
+            /* If the `cursor_row` is within the `desired_matrix`, then it was
+            processed hereinabove and should be skipped at this time. */
+            if (vpos == w->cursor.vpos)
+            continue;
+            int i;
+            /* We'll have to play a little bit with when to
+               detect_input_pending.  If it's done too often,
+               scrolling large windows with repeated scroll-up
+               commands will too quickly pause redisplay. */
+            if (!force_p && ++n_updated % preempt_count == 0)
+              detect_input_pending_ignore_squeezables ();
+            changed_p |= mc_update_window_line (w, vpos, &mouse_face_overwritten_p,
+                                                cursor_matrix, essentials, draw_p);
+            /* Mark all rows below the last visible one in the current
+               matrix as invalid.  This is necessary because of
+               variable line heights.  Consider the case of three
+               successive redisplays, where the first displays 5
+               lines, the second 3 lines, and the third 5 lines again.
+               If the second redisplay wouldn't mark rows in the
+               current matrix invalid, the third redisplay might be
+               tempted to optimize redisplay based on lines displayed
+               in the first redisplay. */
+            if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
+              for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
+                SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
+          }
+      /* Was display preempted? */
+      paused_p = row < end;
+      set_cursor:
+      /* If we jumped here from `set_cursor`, then set the `cursor_matrix`. */
+      if (cursor_matrix == NULL)
+        cursor_matrix = w->current_matrix;
+      /* Reset `row` to 0 so that fake cursors can be drawn on rows preceding the
+      first `row->enabled_p`.  Just prior to the call to `scrolling_window' above,
+      `row` was advanced to the first `row->enabled_p`. */
+      for (struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, 0);
+           desired_row < end
+           && (force_p || !input_pending)
+           /* W32 Emacs crashes on startup without a BUFFERP check. */
+           && BUFFERP (w->contents)
+           && (!NILP (BVAR (XBUFFER (w->contents), mc_conf))
+               || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+               || !NILP (BVAR (XBUFFER (w->contents), fc_visible)));
+           ++desired_row)
+        {
+          int vpos = MATRIX_ROW_VPOS (desired_row, w->desired_matrix);
+          if (desired_row->enabled_p)
+            continue;
+          struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
+          enum mc_row_position row_position = mc_row_position (w, current_row, current_row, vpos);
+          if (current_row->enabled_p)
+            mc_draw_row (w, w->current_matrix, current_row, current_row->glyphs[TEXT_AREA],
+                         current_row->x, current_row->used[TEXT_AREA], vpos,
+                         cursor_matrix, essentials, row_position, draw_p,
+                         SET_CURSOR_ONE);
+        }
+
+      mc_restore_glyph_matrix (saved_desired, w->desired_matrix);
+      mc_restore_glyph_matrix (saved_current, w->current_matrix);
+
+      mc_update_window_erase (w, old_matrix);
+
+      mc_xfree_cache_matrix (w, &old_matrix);
+
+    }
+  // clock_t clock_end = clock();
+  // double cpu_time_used = ((double) (clock_end - clock_start)) / CLOCKS_PER_SEC;
+  // fprintf (stderr, "mc_scrolling_window (%s):  TIME (%f)\n", mc_window (w), cpu_time_used);
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Structure to pass dimensions around.  Used for character bounding
    boxes, glyph matrix dimensions and alike.  */
 
@@ -2241,6 +4059,16 @@ free_window_matrices (struct window *w)
 	  free_glyph_matrix (w->current_matrix);
 	  free_glyph_matrix (w->desired_matrix);
 	  w->current_matrix = w->desired_matrix = NULL;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  mc_xfree_cache_matrix (w, &w->mc_matrix);
+
+/* *************************************************************************** */
+
+
 	}
 
       /* Next window on same level.  */
@@ -3387,6 +5215,26 @@ check_current_matrix_flags (struct window *w)
 static bool
 update_window (struct window *w, bool force_p)
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (trace_redisplay_p)
+    fprintf (stderr, "update_window (%s)\n", mc_window (w));
+
+  struct mc_essentials essentials;
+  mc_set_essentials (w, &essentials);
+
+  mc_update_window_dryrun (w, force_p, essentials);
+
+  struct glyph_matrix *cursor_matrix = NULL;
+
+  bool draw_p = true;
+
+/* *************************************************************************** */
+
+
   struct glyph_matrix *desired_matrix = w->desired_matrix;
   bool paused_p;
   int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
@@ -3460,6 +5308,47 @@ update_window (struct window *w, bool force_p)
 	    }
 	}
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  /* Process the cursor row at the outset if it is within `desired_matrix`.
+  When processing all other rows, we will query the `w->current_matrix` for data
+  relating to the cursor row.  `make_current` (within `update_window_line')
+  updates the `w->current_matrix` for the applicable row.  In doing so, however,
+  the applicable row in the desired matrix is altered such that we can no longer
+  rely upon the accuracy of `ROW->used[TEXT_AREA]`.  Therefore, we must now rely
+  exclusively upon `w->current_matrix' for cursor row based decisions. */
+  for (struct glyph_row *mc_row = row;
+       mc_row < end && (force_p || !input_pending);
+       ++mc_row)
+    {
+      int vpos = MATRIX_ROW_VPOS (mc_row, desired_matrix);
+      if (mc_row->enabled_p
+          && vpos == w->cursor.vpos)
+        {
+          cursor_matrix = desired_matrix;
+          if (!force_p && ++n_updated % preempt_count == 0)
+            detect_input_pending_ignore_squeezables ();
+          changed_p |= (BUFFERP (w->contents)
+                        && (!NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                            || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                            || ! NILP (BVAR (XBUFFER (w->contents), fc_visible))))
+                       ? mc_update_window_line (w, vpos, &mouse_face_overwritten_p,
+                                                cursor_matrix, essentials, draw_p)
+                       : update_window_line (w, vpos, &mouse_face_overwritten_p);
+          if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
+            for (int i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
+              SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
+          break;
+        }
+    }
+
+  cursor_matrix = w->current_matrix;
+
+/* *************************************************************************** */
+
+
       /* Update the rest of the lines.  */
       for (; row < end && (force_p || !input_pending); ++row)
 	/* scrolling_window resets the enabled_p flag of the rows it
@@ -3467,6 +5356,19 @@ update_window (struct window *w, bool force_p)
 	if (row->enabled_p)
 	  {
 	    int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+          /* If the `cursor_row` is within the `desired_matrix`, then it was
+          processed hereinabove and should be skipped at this time. */
+          if (vpos == w->cursor.vpos)
+          continue;
+
+/* *************************************************************************** */
+
+
 	    int i;
 
 	    /* We'll have to play a little bit with when to
@@ -3475,8 +5377,21 @@ update_window (struct window *w, bool force_p)
 	       commands will too quickly pause redisplay.  */
 	    if (!force_p && ++n_updated % preempt_count == 0)
 	      detect_input_pending_ignore_squeezables ();
-	    changed_p |= update_window_line (w, vpos,
-					     &mouse_face_overwritten_p);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+          changed_p |= (BUFFERP (w->contents)
+                        && (!NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                            || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                            || ! NILP (BVAR (XBUFFER (w->contents), fc_visible))))
+                       ? mc_update_window_line (w, vpos, &mouse_face_overwritten_p,
+                                                cursor_matrix, essentials, draw_p)
+                       : update_window_line (w, vpos, &mouse_face_overwritten_p);
+
+/* *************************************************************************** */
+
 
 	    /* Mark all rows below the last visible one in the current
 	       matrix as invalid.  This is necessary because of
@@ -3497,6 +5412,41 @@ update_window (struct window *w, bool force_p)
 
     set_cursor:
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  /* If we jumped here from `set_cursor`, then set the `cursor_matrix`. */
+  if (cursor_matrix == NULL)
+    cursor_matrix = w->current_matrix;
+
+  /* Reset `row` to 0 so that fake cursors can be drawn on rows preceding the
+  first `row->enabled_p`.  Just prior to the call to `scrolling_window' above,
+  `row` was advanced to the first `row->enabled_p`. */
+  for (struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, 0);
+       desired_row < end
+       && (force_p || !input_pending)
+       /* W32 Emacs crashes on startup without a BUFFERP check. */
+       && BUFFERP (w->contents)
+       && (!NILP (BVAR (XBUFFER (w->contents), mc_conf))
+           || !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+           || !NILP (BVAR (XBUFFER (w->contents), fc_visible)));
+       ++desired_row)
+    {
+      int vpos = MATRIX_ROW_VPOS (desired_row, desired_matrix);
+      if (desired_row->enabled_p)
+        continue;
+      struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
+      enum mc_row_position row_position = mc_row_position (w, current_row, current_row, vpos);
+      if (current_row->enabled_p)
+        mc_draw_row (w, w->current_matrix, current_row, current_row->glyphs[TEXT_AREA],
+                     current_row->x, current_row->used[TEXT_AREA], vpos,
+                     cursor_matrix, essentials, row_position, draw_p, SET_CURSOR_TWO);
+    }
+
+/* *************************************************************************** */
+
+
       /* Update the header line after scrolling because a new header
 	 line would otherwise overwrite lines at the top of the window
 	 that can be scrolled.  */
@@ -3512,7 +5462,49 @@ update_window (struct window *w, bool force_p)
 #ifdef HAVE_WINDOW_SYSTEM
 	  if (changed_p && rif->fix_overlapping_area)
 	    {
-	      redraw_overlapped_rows (w, yb);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* `redraw_overlapped_rows':  Redraw lines from the current matrix of window W
+that are overlapped by other rows.  YB is bottom-most y-position in W.  If rows
+overlapping others have been changed, the rows being overlapped have to be
+redrawn.  This won't draw lines that have already been drawn in update_window
+line because overlapped_p in desired rows is 0, so after row assignment
+overlapped_p in current rows is 0. */
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  for (int i = 0; i < w->current_matrix->nrows; ++i)
+    {
+      struct glyph_row *row = w->current_matrix->rows + i;
+      if (!row->enabled_p)
+        break;
+        else if (row->mode_line_p)
+          continue;
+      if (row->overlapped_p)
+        {
+          for (enum glyph_row_area area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+            {
+              output_cursor_to (w, i, 0, row->y, area == TEXT_AREA ? row->x : 0);
+              if (!mc_redraw_row (w, w->current_matrix, row, area, row->x, 0,
+                                  row->used[area], true, DRAW_NORMAL_TEXT,
+                                  UPDATE_WINDOW__REDRAW_OVERLAPPED_ROWS)
+                  && row->used[area])
+                {
+                  FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area], area,
+                                               row->used[area]);
+                  FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
+                }
+            }
+          row->overlapped_p = 0;
+        }
+      if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
+        break;
+    }
+
+/* *************************************************************************** */
+
+
 	      redraw_overlapping_rows (w, yb);
 	    }
 #endif
@@ -3531,10 +5523,21 @@ update_window (struct window *w, bool force_p)
       strcpy (w->current_matrix->method, w->desired_matrix->method);
 #endif
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
 #ifdef HAVE_WINDOW_SYSTEM
+  if (BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    mc_update_window_fringes (w, 0);
+    else
       update_window_fringes (w, 0);
 #endif
 
+/* *************************************************************************** */
+
+
       /* End the update of window W.  Don't set the cursor if we
          paused updating the display because in this case,
          set_window_cursor_after_update hasn't been called, and
diff --git a/src/frame.h b/src/frame.h
index ec8f614..eeaf71e 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -205,6 +205,16 @@ struct frame
   Lisp_Object tool_bar_items;
   /* tool_bar_items should be the last Lisp_Object member.  */
 
+
+/* *************************************************************************** */
+/* 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 335a6eb..d70c55f 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -438,6 +438,460 @@ static unsigned short empty_line_bits[] = {
 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
 #define FRBITS(bits)  bits, STANDARD_BITMAP_HEIGHT (bits)
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+/* `+-fringe-helper-decimal' defined in `crosshairs.el` */
+
+/* TODO:  Consider adding the following fringe 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") */
+
+/* 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
+      "......xx"
+      "......xx"
+      "......xx"
+      ".xx...xx"
+      "..xx..xx"
+      "...xx.xx"
+      "xxxxxxxx"
+      "xxxxxxxx"
+      "...xx.xx"
+      "..xx..xx"
+      ".xx...xx"
+      "......xx"
+      "......xx"
+      "......xx")
+*/
+static unsigned short mc_reversed_vertical_bar_right_arrow_bits[] ={
+  0x3, 0x3, 0x3, 0x63, 0x33, 0x1b, 0xff, 0xff, 0x1b, 0x33, 0x63, 0x3, 0x3, 0x3};
+
+/* 26
+    (+-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};
+
+/* 27
+    (+-fringe-helper-hexadecimal
+      "xxxxxxxx"
+      "x.....xx"
+      "x.....xx"
+      "x.xx..xx"
+      "x..xx.xx"
+      "x...xxxx"
+      "xxxxxxxx"
+      "xxxxxxxx"
+      "x...xxxx"
+      "x..xx.xx"
+      "x.xx..xx"
+      "x.....xx"
+      "x.....xx"
+      "xxxxxxxx")
+*/
+static unsigned short mc_reversed_hollow_rectangle_right_arrow_bits[] ={
+  0xff, 0x81, 0x81, 0xb1, 0x99, 0x8d, 0xff,
+  0xff, 0x8d, 0x99, 0xb1, 0x81, 0x81, 0xff};
+
+/* 28
+    (+-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};
+
+/* 29
+    (+-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};
+
+/* 30
+    (+-fringe-helper-hexadecimal
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx"
+      "......xx")
+*/
+static unsigned short mc_reversed_vertical_bar_bits[] ={
+  0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3};
+
+/* 31
+    (+-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};
+
+/* 32
+    (+-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};
+
+/* 33
+    (+-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};
+
+/* 34
+    (+-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};
+
+/* 35
+    (+-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};
+
+/* 36
+    (+-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};
+
+/* 37
+    (+-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};
+
+/* 38
+    (+-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};
+
+/* 39
+    (+-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};
+
+/* 40
+    (+-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};
+
+/* 41
+    (+-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};
+
+/* 42
+    (+-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};
+
+/* 43
+    (+-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};
+
+/* 44
+    (+-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};
+
+/* 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."
+      "........")
+*/
+static unsigned short mc_triple_angle_up_bits[] ={
+  0x00, 0x10, 0x28, 0x44, 0x92, 0x28, 0x44, 0x92, 0x28, 0x44, 0x82, 0x00};
+
+/* 46
+    (+-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};
+
+/* 47
+    (+-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};
+
+/* 48
+    (+-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};
+
 /* NOTE:  The order of these bitmaps must match the sequence
    used in fringe.el to define the corresponding symbols.  */
 
@@ -467,8 +921,1074 @@ 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 },
+
+  /* 24 */
+  {FRBITS (mc_vertical_bar_right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 25 */
+  {FRBITS (mc_reversed_vertical_bar_right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 26 */
+  {FRBITS (mc_hollow_rectangle_right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 27 */
+  {FRBITS (mc_reversed_hollow_rectangle_right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 28 */
+  {FRBITS (mc_hollow_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 29 */
+  {FRBITS (mc_vertical_bar_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 30 */
+  {FRBITS (mc_reversed_vertical_bar_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 31 */
+  {FRBITS (mc_backslash_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 32 */
+  {FRBITS (mc_vertical_bar_backslash_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 33 */
+  {FRBITS (mc_pilcrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 34 */
+  {FRBITS (mc_smiley_face_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 35 */
+  {FRBITS (mc_single_angle_right_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 36 */
+  {FRBITS (mc_single_angle_left_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 37 */
+  {FRBITS (mc_double_angle_right_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 38 */
+  {FRBITS (mc_double_angle_left_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 39 */
+  {FRBITS (mc_triple_angle_right_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 40 */
+  {FRBITS (mc_triple_angle_left_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 41 */
+  {FRBITS (mc_single_angle_up_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 42 */
+  {FRBITS (mc_single_angle_down_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 43 */
+  {FRBITS (mc_double_angle_up_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 44 */
+  {FRBITS (mc_double_angle_down_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 45 */
+  {FRBITS (mc_triple_angle_up_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 46 */
+  {FRBITS (mc_triple_angle_down_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 47 */
+  {FRBITS (mc_quadruple_angle_up_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
+  /* 48 */
+  {FRBITS (mc_quadruple_angle_down_bits), 8, 0, ALIGN_BITMAP_CENTER, 0},
 };
 
+/* Use this to suppress gcc's `...may be used before initialized' warnings. */
+#ifdef lint
+# define MC_IF_LINT(Code) Code
+#else
+# define MC_IF_LINT(Code) /* empty */
+#endif
+
+static struct fringe_bitmap * get_fringe_bitmap_data (int);
+
+/* 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. */
+int
+mc_get_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 = mc_assq (bitmap, cmap);
+      if (CONSP (bm1))
+  {
+    if ((bm1 = XCDR (bm1)), NILP (bm1))
+      return MC_NO_FRINGE_BITMAP;
+    if (CONSP (bm1))
+      {
+        ln1 = XFIXNUM (Flength (bm1));
+        if (partial_p)
+          {
+            if (ln1 > ix2)
+              {
+                bm = mc_nth (ix2, bm1);
+                if (!EQ (bm, Qt))
+                  goto found;
+              }
+          }
+          else
+            {
+              if (ln1 > ix1)
+                {
+                  bm = mc_nth (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 = mc_assq (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 = mc_nth (ix2, bm2);
+                          if (!EQ (bm, Qt))
+                            goto found;
+                        }
+                    }
+                }
+            }
+        }
+    }
+  if (ln1 > ix1)
+    {
+      bm = mc_nth (ix1, bm1);
+      if (!EQ (bm, Qt))
+        goto found;
+    }
+  if (ln2 > ix1)
+    {
+      bm = mc_nth (ix1, bm2);
+      if (!EQ (bm, Qt))
+        goto found;
+      return MC_NO_FRINGE_BITMAP;
+    }
+    else if ((bm = bm2, NILP (bm)))
+      return MC_NO_FRINGE_BITMAP;
+  found:
+  return lookup_fringe_bitmap (bm);
+}
+
+static int
+mc_get_logical_cursor_bitmap (struct window *w, Lisp_Object cursor)
+{
+  Lisp_Object cmap, bm = Qnil;
+  if ((cmap = BVAR (XBUFFER (w->contents), fringe_cursor_alist)), !NILP (cmap))
+    {
+      bm = mc_assq (cursor, cmap);
+      if (CONSP (bm))
+        {
+          if ((bm = XCDR (bm)), NILP (bm))
+            return MC_NO_FRINGE_BITMAP;
+          return lookup_fringe_bitmap (bm);
+        }
+    }
+  if (EQ (cmap, BVAR (&buffer_defaults, fringe_cursor_alist)))
+    return MC_NO_FRINGE_BITMAP;
+  bm = mc_assq (cursor, BVAR (&buffer_defaults, fringe_cursor_alist));
+  if (!CONSP (bm) || ((bm = XCDR (bm)), NILP (bm)))
+    return MC_NO_FRINGE_BITMAP;
+  return lookup_fringe_bitmap (bm);
+}
+
+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);
+  /* 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.  */
+  if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
+    {
+      bm1 = mc_assq (bitmap, cmap);
+      if (CONSP (bm1))
+        {
+          if ((bm1 = XCDR (bm1)), NILP (bm1))
+            return MC_NO_FRINGE_BITMAP;
+          if (CONSP (bm1))
+            {
+              ln1 = XFIXNUM (Flength (bm1));
+              if (partial_p)
+                {
+                  if (ln1 > ix2)
+                    {
+                      bm = mc_nth (ix2, bm1);
+                      if (!EQ (bm, Qt))
+                        goto found;
+                    }
+                }
+                else
+                  {
+                    if (ln1 > ix1)
+                      {
+                        bm = mc_nth (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 = mc_assq (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 = mc_nth (ix2, bm2);
+                          if (!EQ (bm, Qt))
+                            goto found;
+                        }
+                    }
+                }
+            }
+        }
+    }
+  if (ln1 > ix1)
+    {
+      bm = mc_nth (ix1, bm1);
+      if (!EQ (bm, Qt))
+        goto found;
+    }
+  if (ln2 > ix1)
+    {
+      bm = mc_nth (ix1, bm2);
+      if (!EQ (bm, Qt))
+        goto found;
+      return MC_NO_FRINGE_BITMAP;
+    }
+    else if ((bm = bm2, NILP (bm)))
+      return MC_NO_FRINGE_BITMAP;
+  found:
+  return lookup_fringe_bitmap (bm);
+}
+
+/* Recalculate the bitmaps to show in the fringes of window W.
+   Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
+   If KEEP_CURRENT_P is 0, update current_matrix too. */
+bool
+mc_update_window_fringes (struct window *w, bool keep_current_p)
+{
+  struct glyph_row *row, *cur = 0;
+  int yb = window_text_bottom_y (w);
+  int rn, nrows = w->current_matrix->nrows;
+  int y;
+  bool redraw_p = 0;
+  Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
+  Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
+  Lisp_Object empty_pos;
+  Lisp_Object ind = Qnil;
+#define MAX_BITMAP_CACHE (8*4)
+  int bitmap_cache[MAX_BITMAP_CACHE];
+  int top_ind_rn, bot_ind_rn;
+  int top_ind_min_y, bot_ind_max_y;
+  /* top_ind_rn is set to a nonnegative value whenever
+     row->indicate_bob_p is set, so it's OK that top_row_ends_at_zv_p
+     is not initialized here.  Similarly for bot_ind_rn,
+     row->indicate_eob_p and bot_row_ends_at_zv_p.  */
+  int top_row_ends_at_zv_p MC_IF_LINT (= 0), bot_row_ends_at_zv_p MC_IF_LINT (= 0);
+  if (w->pseudo_window_p)
+    return 0;
+  if (!MINI_WINDOW_P (w)
+      && (ind = BVAR (XBUFFER (w->contents), indicate_buffer_boundaries), !NILP (ind)))
+    {
+      if (EQ (ind, Qleft) || EQ (ind, Qright))
+        boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
+        else if (CONSP (ind)
+                 && CONSP (XCAR (ind)))
+        {
+          Lisp_Object pos;
+          if (pos = mc_assq (Qt, ind), !NILP (pos))
+            boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
+          if (pos = mc_assq (Qtop, ind), !NILP (pos))
+            boundary_top = XCDR (pos);
+          if (pos = mc_assq (Qbottom, ind), !NILP (pos))
+            boundary_bot = XCDR (pos);
+          if (pos = mc_assq (Qup, ind), !NILP (pos))
+            arrow_top = XCDR (pos);
+          if (pos = mc_assq (Qdown, ind), !NILP (pos))
+            arrow_bot = XCDR (pos);
+        }
+        else
+          /* Anything else means boundary on left and no arrows.  */
+          boundary_top = boundary_bot = Qleft;
+    }
+  top_ind_rn = bot_ind_rn = -1;
+  if (!NILP (ind))
+    {
+      for (y = w->vscroll, rn = 0;
+           y < yb && rn < nrows;
+           y += row->height, ++rn)
+        {
+          row = w->desired_matrix->rows + rn;
+          if (!row->enabled_p)
+            row = w->current_matrix->rows + rn;
+          row->indicate_bob_p = row->indicate_top_line_p = 0;
+          row->indicate_eob_p = row->indicate_bottom_line_p = 0;
+          if (!row->mode_line_p)
+            {
+              if (top_ind_rn < 0 && row->visible_height > 0)
+                {
+                  if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->contents))
+                      && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
+                    row->indicate_bob_p = !NILP (boundary_top);
+                    else
+                      row->indicate_top_line_p = !NILP (arrow_top);
+                  top_ind_rn = rn;
+                }
+              if (bot_ind_rn < 0)
+                {
+                  if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->contents))
+                      && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
+                    row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
+                    else if (y + row->height >= yb)
+                      row->indicate_bottom_line_p = !NILP (arrow_bot), bot_ind_rn = rn;
+                }
+            }
+        }
+    }
+  empty_pos = BVAR (XBUFFER (w->contents), indicate_empty_lines);
+  if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
+    empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
+  for (y = 0; y < MAX_BITMAP_CACHE; y++)
+    bitmap_cache[y] = -1;
+#define MC_LEFT_FRINGE(cache, which, partial_p)			\
+  (bitmap_cache[cache*4+partial_p] >= 0				\
+   ? bitmap_cache[cache*4+partial_p]				\
+   : (bitmap_cache[cache*4+partial_p] =				\
+      mc_get_logical_fringe_bitmap (w, which, 0, partial_p)))
+#define MC_RIGHT_FRINGE(cache, which, partial_p)			\
+  (bitmap_cache[cache*4+2+partial_p] >= 0			\
+   ? bitmap_cache[cache*4+2+partial_p]				\
+   : (bitmap_cache[cache*4+2+partial_p] =			\
+      mc_get_logical_fringe_bitmap (w, which, 1, partial_p)))
+  /* Extend top-aligned top indicator (or bottom-aligned bottom
+     indicator) to adjacent rows if it doesn't fit in one row.  */
+  top_ind_min_y = bot_ind_max_y = -1;
+  if (top_ind_rn >= 0)
+    {
+      int bn = MC_NO_FRINGE_BITMAP;
+      row = w->desired_matrix->rows + top_ind_rn;
+      if (!row->enabled_p)
+        row = w->current_matrix->rows + top_ind_rn;
+      top_row_ends_at_zv_p = row->ends_at_zv_p;
+      if (row->indicate_bob_p)
+        {
+          if (EQ (boundary_top, Qleft))
+            bn = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
+                  ? MC_LEFT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
+                  : MC_LEFT_FRINGE (2, Qtop, 0));
+            else
+              bn = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
+                    ? MC_RIGHT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
+                    : MC_RIGHT_FRINGE (2, Qtop, 0));
+        }
+        else if (row->indicate_top_line_p)
+          {
+            if (EQ (arrow_top, Qleft))
+              bn = MC_LEFT_FRINGE (6, Qup, 0);
+              else
+                bn = MC_RIGHT_FRINGE (6, Qup, 0);
+          }
+      if (bn != MC_NO_FRINGE_BITMAP)
+        {
+          struct fringe_bitmap *fb = get_fringe_bitmap_data (bn);
+          if (fb->align == ALIGN_BITMAP_TOP && fb->period == 0)
+            {
+              struct glyph_row *row1;
+              int top_ind_max_y;
+              top_ind_min_y = WINDOW_HEADER_LINE_HEIGHT (w);
+              top_ind_max_y = top_ind_min_y + fb->height;
+              if (top_ind_max_y > yb)
+                top_ind_max_y = yb;
+              for (y = row->y + row->height, rn = top_ind_rn + 1;
+                   y < top_ind_max_y && rn < nrows;
+                   y += row1->height, rn++)
+                {
+                  if (bot_ind_rn >= 0 && rn >= bot_ind_rn)
+                    break;
+                  row1 = w->desired_matrix->rows + rn;
+                  if (!row1->enabled_p)
+                    row1 = w->current_matrix->rows + rn;
+                  row1->indicate_bob_p = row->indicate_bob_p;
+                  row1->indicate_top_line_p = row->indicate_top_line_p;
+                }
+            }
+        }
+    }
+  if (bot_ind_rn >= 0)
+    {
+      int bn = MC_NO_FRINGE_BITMAP;
+      row = w->desired_matrix->rows + bot_ind_rn;
+      if (!row->enabled_p)
+        row = w->current_matrix->rows + bot_ind_rn;
+      bot_row_ends_at_zv_p = row->ends_at_zv_p;
+      if (row->indicate_eob_p)
+        {
+          if (EQ (boundary_bot, Qleft))
+            bn = MC_LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
+            else
+              bn = MC_RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
+        }
+        else if (row->indicate_bottom_line_p)
+          {
+            if (EQ (arrow_bot, Qleft))
+              bn = MC_LEFT_FRINGE (7, Qdown, 0);
+              else
+                bn = MC_RIGHT_FRINGE (7, Qdown, 0);
+          }
+      if (bn != MC_NO_FRINGE_BITMAP)
+        {
+          struct fringe_bitmap *fb = get_fringe_bitmap_data (bn);
+          if (fb->align == ALIGN_BITMAP_BOTTOM && fb->period == 0)
+            {
+              struct glyph_row *row1;
+              int bot_ind_min_y;
+              bot_ind_max_y = row->y + row->visible_height;
+              bot_ind_min_y = bot_ind_max_y - fb->height;
+              if (bot_ind_min_y < WINDOW_HEADER_LINE_HEIGHT (w))
+                bot_ind_min_y = WINDOW_HEADER_LINE_HEIGHT (w);
+              for (y = row->y, rn = bot_ind_rn - 1;
+                   y >= bot_ind_min_y && rn >= 0;
+                   y -= row1->height, rn--)
+                {
+                  if (top_ind_rn >= 0 && rn <= top_ind_rn)
+                    break;
+                  row1 = w->desired_matrix->rows + rn;
+                  if (!row1->enabled_p)
+                    row1 = w->current_matrix->rows + rn;
+                  row1->indicate_eob_p = row->indicate_eob_p;
+                  row1->indicate_bottom_line_p = row->indicate_bottom_line_p;
+                }
+            }
+        }
+    }
+  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);
+  for (y = w->vscroll, rn = 0;
+       y < yb && rn < nrows;
+       y += row->height, rn++)
+    {
+  int left, right;
+  unsigned left_face_id, right_face_id;
+  int left_offset, right_offset;
+  bool periodic_p;
+  row = w->desired_matrix->rows + rn;
+  cur = w->current_matrix->rows + rn;
+  int vnth_dm = MATRIX_ROW_VPOS (w->desired_matrix->rows + rn, w->desired_matrix);
+  int vnth_cm = MATRIX_ROW_VPOS (w->current_matrix->rows + rn, w->current_matrix);
+  enum mc_row_position row_position = mc_row_position (w, cur, cur, vnth_cm);
+  int mc_left_fringe_bitmap = MC_NO_FRINGE_BITMAP;
+  int mc_left_fringe_face_id = DEFAULT_FACE_ID;
+  int mc_right_fringe_bitmap = MC_NO_FRINGE_BITMAP;
+  int mc_right_fringe_face_id = DEFAULT_FACE_ID;
+  enum mc_cache_type cache_type = CH_CACHE;
+  for (int nth = 0;
+       mc_traverse_cache_p (w->mc_matrix, cache_type, vnth_cm, nth);
+       ++nth)
+    {
+      //  int x = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].x;
+      //  int fx = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].fx;
+      //  int y = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].y;
+      //  int fy = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].fy;
+      //  int hpos = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].hpos;
+      int vpos = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].vpos;
+      //  int wd = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].wd;
+      //  int h = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].h;
+      enum mc_cursor_type cursor_type = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].cursor_type;
+      //  int cursor_width = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].cursor_width;
+      //  struct mc_RGB lsl_fg = {.red = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].fg.red,
+      //                          .green = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].fg.green,
+      //                          .blue = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].fg.blue};
+      //  struct mc_RGB lsl_bg = {.red = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].bg.red,
+      //                          .green = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].bg.green,
+      //                          .blue = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].bg.blue};
+      bool active_p = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].active_p;
+      enum mc_flavor glyph_flavor = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].glyph_flavor;
+      bool enabled_p = w->mc_matrix.vpos[vnth_cm].cache[cache_type][nth].enabled_p;
+      if ((vpos == vnth_dm || vpos == vnth_cm)
+          && glyph_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
+          && enabled_p)
+        {
+          int fringe_bitmap = MC_NO_FRINGE_BITMAP;
+          enum face_id overlay_arrow_face_id =
+            (!active_p
+             && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+            ? lookup_named_face (w, f, intern ("+-overlay-arrow-inactive-pre-zv-face"), true)
+            : (active_p)
+              ? lookup_named_face (w, f, intern ("+-overlay-arrow-pre-zv-face"), true)
+            : DEFAULT_FACE_ID;
+          mc_left_fringe_face_id = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                    ? overlay_arrow_face_id
+                                    : DEFAULT_FACE_ID;
+          if (w->hscroll != 0)
+            fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-overlay-arrow"), false, true);
+            else
+              fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-overlay-arrow"), true, true);
+          mc_left_fringe_bitmap = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                   ? fringe_bitmap
+                                   : MC_NO_FRINGE_BITMAP;
+        }
+        else if ((vpos == vnth_dm || vpos == vnth_cm)
+                 && glyph_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)
+                 && enabled_p)
+          {
+            int fringe_bitmap = MC_NO_FRINGE_BITMAP;
+            enum face_id overlay_arrow_face_id =
+              (!active_p
+               && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+              ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-inactive-pre-zv-face"), true)
+              : (active_p)
+                ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-pre-zv-face"), true)
+              : DEFAULT_FACE_ID;
+            mc_left_fringe_face_id = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                      ? overlay_arrow_face_id
+                                      : DEFAULT_FACE_ID;
+            if (hscl_all_perm_0_p)
+              fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), false, false);
+              else if (hscl_all_perm_1_p)
+                fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), true, false);
+                else if (hscl_all_perm_2_p)
+                  fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), false, true);
+                  else if (hscl_perm_p)
+                    fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), true, true);
+                    else if (hscl_all_temp_p)
+                      fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-temp"), false, false);
+                      else if (hscl_temp_p)
+                        fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-temp"), true, false);
+            mc_left_fringe_bitmap = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                     ? fringe_bitmap
+                                     : MC_NO_FRINGE_BITMAP;
+          }
+          else if ((vpos == vnth_dm || vpos == vnth_cm)
+                    && (glyph_flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW
+                        || glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                        || glyph_flavor == MC_HOLLOW_RECTANGLE
+                        || glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+                        || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                        || glyph_flavor == MC_VERTICAL_BAR
+                        || glyph_flavor == MC_REVERSED_VERTICAL_BAR
+                        || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH)
+                    && enabled_p)
+            {
+              Lisp_Object bitmap_flavor = (glyph_flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW)
+                                          ? Qmc_hollow_rectangle_right_arrow
+                                          : (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW)
+                                            ? Qmc_reversed_hollow_rectangle_right_arrow
+                                          : (glyph_flavor == MC_HOLLOW_RECTANGLE)
+                                            ? Qmc_hollow_rectangle
+                                          : (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW)
+                                            ? Qmc_vertical_bar_right_arrow
+                                          : (glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW)
+                                            ? Qmc_reversed_vertical_bar_right_arrow
+                                          : (glyph_flavor == MC_VERTICAL_BAR)
+                                            ? Qmc_vertical_bar
+                                          : (glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+                                            ? Qmc_reversed_vertical_bar
+                                          : (glyph_flavor == MC_VERTICAL_BAR_BACKSLASH)
+                                            ? Qmc_vertical_bar_backslash
+                                          : Qnil;
+              mc_right_fringe_bitmap = (cursor_type == MC_RIGHT_FRINGE_BITMAP)
+                                        ? lookup_fringe_bitmap (bitmap_flavor)
+                                        : MC_NO_FRINGE_BITMAP;
+              mc_right_fringe_face_id =
+                (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                 && row_position == PRE_ZV
+                 && (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                     || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                     || glyph_flavor == MC_REVERSED_VERTICAL_BAR))
+                  ? lookup_named_face (w, f, intern ("+-reversed-bar-pre-zv-face"), true)
+                : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                   && row_position == AT_ZV
+                   && (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                       || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                       || glyph_flavor == MC_REVERSED_VERTICAL_BAR))
+                  ? lookup_named_face (w, f, intern ("+-reversed-bar-at-zv-face"), true)
+                : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                   && row_position == POST_ZV
+                   && (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                       || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                       || glyph_flavor == MC_REVERSED_VERTICAL_BAR))
+                  ? lookup_named_face (w, f, intern ("+-reversed-bar-post-zv-face"), true)
+                : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                   && row_position == PRE_ZV
+                   && glyph_flavor != MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR)
+                  ? lookup_named_face (w, f, intern ("+-bar-pre-zv-face"), true)
+                : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                   && row_position == AT_ZV
+                   && glyph_flavor != MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR)
+                  ? lookup_named_face (w, f, intern ("+-bar-at-zv-face"), true)
+                : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                   && row_position == POST_ZV
+                   && glyph_flavor != MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                   && glyph_flavor != MC_REVERSED_VERTICAL_BAR)
+                  ? lookup_named_face (w, f, intern ("+-bar-post-zv-face"), true)
+                : DEFAULT_FACE_ID;
+            }
+        }
+      if (!row->enabled_p)
+        row = cur;
+      left_face_id = right_face_id = DEFAULT_FACE_ID;
+      left_offset = right_offset = 0;
+      periodic_p = 0;
+      /* Decide which bitmap to draw in the left fringe.  */
+      if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
+        left = MC_NO_FRINGE_BITMAP;
+      else if (row->left_user_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        {
+          left = row->left_user_fringe_bitmap;
+          left_face_id = row->left_user_fringe_face_id;
+        }
+      else if ((!row->reversed_p && row->truncated_on_left_p)
+               || (row->reversed_p && row->truncated_on_right_p))
+        left = MC_LEFT_FRINGE (0, Qtruncation, 0);
+      else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
+        {
+          left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
+                 ? MC_LEFT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
+                 : MC_LEFT_FRINGE (2, Qtop, 0));
+          if (top_ind_min_y >= 0)
+            left_offset = top_ind_min_y - row->y;
+        }
+      else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
+        {
+          left = MC_LEFT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
+          if (bot_ind_max_y >= 0)
+            left_offset = bot_ind_max_y - (row->y + row->visible_height);
+        }
+      else if ((!row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row))
+               || (row->reversed_p && row->continued_p))
+        left = MC_LEFT_FRINGE (4, Qcontinuation, 0);
+      else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
+        left = MC_LEFT_FRINGE (5, Qempty_line, 0);
+      else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
+        {
+          left = MC_LEFT_FRINGE (6, Qup, 0);
+          if (top_ind_min_y >= 0)
+            left_offset = top_ind_min_y - row->y;
+        }
+      else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
+        {
+          left = MC_LEFT_FRINGE (7, Qdown, 0);
+          if (bot_ind_max_y >= 0)
+            left_offset = bot_ind_max_y - (row->y + row->visible_height);
+        }
+      else
+        left = MC_NO_FRINGE_BITMAP;
+      /* Decide which bitmap to draw in the right fringe.  */
+      if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
+        right = MC_NO_FRINGE_BITMAP;
+      else if (row->right_user_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        {
+          right = row->right_user_fringe_bitmap;
+          right_face_id = row->right_user_fringe_face_id;
+        }
+      else if ((!row->reversed_p && row->truncated_on_right_p)
+               || (row->reversed_p && row->truncated_on_left_p))
+        right = MC_RIGHT_FRINGE (0, Qtruncation, 0);
+      else if (row->indicate_bob_p && EQ (boundary_top, Qright))
+        {
+          right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
+             ? MC_RIGHT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
+             : MC_RIGHT_FRINGE (2, Qtop, 0));
+          if (top_ind_min_y >= 0)
+            right_offset = top_ind_min_y - row->y;
+        }
+      else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
+        {
+          right = MC_RIGHT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
+          if (bot_ind_max_y >= 0)
+            right_offset = bot_ind_max_y - (row->y + row->visible_height);
+        }
+      else if ((!row->reversed_p && row->continued_p)
+               || (row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row)))
+        right = MC_RIGHT_FRINGE (4, Qcontinuation, 0);
+      else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
+        {
+          right = MC_RIGHT_FRINGE (6, Qup, 0);
+          if (top_ind_min_y >= 0)
+            right_offset = top_ind_min_y - row->y;
+        }
+      else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
+        {
+          right = MC_RIGHT_FRINGE (7, Qdown, 0);
+          if (bot_ind_max_y >= 0)
+            right_offset = bot_ind_max_y - (row->y + row->visible_height);
+        }
+      else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
+        right = MC_RIGHT_FRINGE (5, Qempty_line, 0);
+      else
+        right = MC_NO_FRINGE_BITMAP;
+      periodic_p = (get_fringe_bitmap_data (left)->period != 0
+                    || get_fringe_bitmap_data (right)->period != 0);
+      if (row->y != cur->y
+          || row->visible_height != cur->visible_height
+          || row->ends_at_zv_p != cur->ends_at_zv_p
+          || left != cur->left_fringe_bitmap
+          || right != cur->right_fringe_bitmap
+          || left_face_id != cur->left_fringe_face_id
+          || right_face_id != cur->right_fringe_face_id
+          || left_offset != cur->left_fringe_offset
+          || right_offset != cur->right_fringe_offset
+          || periodic_p != cur->fringe_bitmap_periodic_p
+          || cur->redraw_fringe_bitmaps_p)
+        {
+          redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
+          if (!keep_current_p)
+            {
+              cur->redraw_fringe_bitmaps_p = 1;
+              if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP
+                  || mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->fringe_bitmap_periodic_p = false;
+                else
+                  cur->fringe_bitmap_periodic_p = periodic_p;
+              if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->left_fringe_bitmap = mc_left_fringe_bitmap;
+                else
+                  cur->left_fringe_bitmap = left;
+              if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->left_fringe_face_id = mc_left_fringe_face_id;
+                else
+                  cur->left_fringe_face_id = left_face_id;
+              if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->left_fringe_offset = 0;
+                else
+                  cur->left_fringe_offset = left_offset;
+              if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->right_fringe_bitmap = mc_right_fringe_bitmap;
+                else
+                  cur->right_fringe_bitmap = right;
+              if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->right_fringe_face_id = mc_right_fringe_face_id;
+                else
+                  cur->right_fringe_face_id = right_face_id;
+              if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+                cur->right_fringe_offset = 0;
+                else
+                  cur->right_fringe_offset = right_offset;
+            }
+        }
+      if (row->overlay_arrow_bitmap < 0)
+        row->overlay_arrow_bitmap = mc_get_logical_fringe_bitmap (w, Qoverlay_arrow, 0, 0);
+      if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
+        {
+          redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
+          if (!keep_current_p)
+            {
+              cur->redraw_fringe_bitmaps_p = 1;
+              cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
+            }
+        }
+      if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP
+          || mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->fringe_bitmap_periodic_p = false;
+        else
+          row->fringe_bitmap_periodic_p = periodic_p;
+      if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->left_fringe_bitmap = mc_left_fringe_bitmap;
+        else
+          row->left_fringe_bitmap = left;
+      if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->left_fringe_face_id = mc_left_fringe_face_id;
+        else
+          row->left_fringe_face_id = left_face_id;
+      if (mc_left_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->left_fringe_offset = 0;
+        else
+          row->left_fringe_offset = left_offset;
+      if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->right_fringe_bitmap = mc_right_fringe_bitmap;
+        else
+          row->right_fringe_bitmap = right;
+      if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->right_fringe_face_id = mc_right_fringe_face_id;
+        else
+          row->right_fringe_face_id = right_face_id;
+      if (mc_right_fringe_bitmap != MC_NO_FRINGE_BITMAP)
+        row->right_fringe_offset = 0;
+        else
+          row->right_fringe_offset = right_offset;
+    }
+  return redraw_p && !keep_current_p;
+}
+
+static Lisp_Object *fringe_faces;
+
+/* Draw the bitmap WHICH in one of the left or right fringes of
+   window W.  ROW is the glyph row for which to display the bitmap; it
+   determines the vertical position at which the bitmap has to be
+   drawn.
+   LEFT_P is 1 for left fringe, 0 for right fringe.
+*/
+static void
+mc_draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int overlay, int which)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct draw_fringe_bitmap_params p;
+  struct fringe_bitmap *fb;
+  int period;
+  int face_id = DEFAULT_FACE_ID;
+  int offset, header_line_height;
+  p.overlay_p = (overlay & 1) == 1;
+  p.cursor_p = (overlay & 2) == 2;
+  if (which != MC_NO_FRINGE_BITMAP)
+    {
+      offset = 0;
+    }
+    else if (left_p)
+      {
+        which = row->left_fringe_bitmap;
+        face_id = row->left_fringe_face_id;
+        offset = row->left_fringe_offset;
+      }
+      else
+        {
+          which = row->right_fringe_bitmap;
+          face_id = row->right_fringe_face_id;
+          offset = row->right_fringe_offset;
+        }
+  if (face_id == DEFAULT_FACE_ID)
+    {
+      Lisp_Object face = fringe_faces[which];
+      face_id = NILP (face) ? lookup_named_face (w, f, Qfringe, false)
+                            : lookup_derived_face (w, f, face, FRINGE_FACE_ID, 0);
+      if (face_id < 0)
+        face_id = FRINGE_FACE_ID;
+    }
+  fb = get_fringe_bitmap_data (which);
+  period = fb->period;
+  /* Convert row to frame coordinates.  */
+  p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y) + offset;
+  p.which = which;
+  p.bits = fb->bits;
+  p.wd = fb->width;
+  p.h = fb->height;
+  p.dh = (period > 0 ? (p.y % period) : 0);
+  p.h -= p.dh;
+  /* Adjust y to the offset in the row to start drawing the bitmap.  */
+  switch (fb->align)
+    {
+    case ALIGN_BITMAP_CENTER:
+      p.y += (row->height - p.h) / 2;
+      break;
+    case ALIGN_BITMAP_BOTTOM:
+      p.y += (row->visible_height - p.h);
+      break;
+    case ALIGN_BITMAP_TOP:
+      break;
+    }
+  p.face = FACE_FROM_ID (f, face_id);
+  if (p.face == NULL)
+    {
+      /* This could happen after clearing face cache.
+      But it shouldn't happen anymore.  ++kfs */
+      return;
+    }
+  prepare_face_for_display (f, p.face);
+  /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
+     the fringe.  */
+  p.bx = -1;
+  header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+  p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
+  p.ny = row->visible_height;
+  if (left_p)
+    {
+      int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
+      int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+           ? LEFT_MARGIN_AREA
+           : TEXT_AREA));
+      if (p.wd > wd)
+        p.wd = wd;
+      p.x = x - p.wd - (wd - p.wd) / 2;
+      if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
+        {
+          /* If W has a vertical border to its left, don't draw over it.  */
+          wd -= ((!WINDOW_LEFTMOST_P (w)
+            /* This could be wrong when we allow window local
+               right dividers - but the window on the left is hard
+               to get.  */
+            && !FRAME_RIGHT_DIVIDER_WIDTH (f)
+            && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+            /* But don't reduce the fringe width if the window
+               has a left margin, because that means we are not
+               in danger of drawing over the vertical border,
+               and OTOH leaving out that one pixel leaves behind
+               traces of the cursor, if it was in column zero
+               before drawing non-empty margin area.  */
+            && w->left_margin_cols == 0)
+           ? 1 : 0);
+          p.bx = x - wd;
+          p.nx = wd;
+        }
+    }
+  else
+    {
+      int x = window_box_right (w,
+        (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+         ? RIGHT_MARGIN_AREA
+         : TEXT_AREA));
+      int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
+      if (p.wd > wd)
+        p.wd = wd;
+      p.x = x + (wd - p.wd) / 2;
+      /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
+   the fringe.  */
+      if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
+        {
+          p.bx = x;
+          p.nx = wd;
+        }
+    }
+  if (p.x >= WINDOW_BOX_LEFT_EDGE_X (w)
+      && (p.x + p.wd) <= WINDOW_BOX_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w))
+    FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
+}
+
+void
+mc_draw_fringe_bitmap (struct window *w, struct glyph_row *row, int left_p, enum mc_cursor_type cursor_type)
+{
+  int overlay = 0;
+  if (left_p == row->reversed_p && row->cursor_in_fringe_p)
+    {
+      Lisp_Object cursor = Qnil;
+      switch (cursor_type)
+        {
+        case MC_FRAMED_BOX:
+          if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
+            cursor = Qhollow;
+          else
+            cursor = Qhollow_small;
+          break;
+        case MC_HOLLOW_BOX:
+          if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
+            cursor = Qhollow;
+          else
+            cursor = Qhollow_small;
+          break;
+        case MC_FILLED_BOX:
+          cursor = Qbox;
+          break;
+        case MC_BAR:
+          cursor = Qbar;
+          break;
+        case MC_HBAR:
+          cursor = Qhbar;
+          break;
+        case MC_NO_FRINGE_BITMAP:
+        case MC_NO_CURSOR:
+        case MC_RIGHT_FRINGE_BITMAP:
+        case MC_LEFT_FRINGE_BITMAP:
+        default:
+          w->phys_cursor_on_p = 0;
+          row->cursor_in_fringe_p = 0;
+          break;
+        }
+      if (!NILP (cursor))
+        {
+          int bm = mc_get_logical_cursor_bitmap (w, cursor);
+          if (bm != MC_NO_FRINGE_BITMAP)
+            {
+              mc_draw_fringe_bitmap_1 (w, row, left_p, 2, bm);
+              overlay = EQ (cursor, Qbox) ? 3 : 1;
+            }
+        }
+    }
+  mc_draw_fringe_bitmap_1 (w, row, left_p, overlay, MC_NO_FRINGE_BITMAP);
+  if (left_p && row->overlay_arrow_bitmap != MC_NO_FRINGE_BITMAP)
+    mc_draw_fringe_bitmap_1 (w, row, 1, 1, row->overlay_arrow_bitmap);
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 #define NO_FRINGE_BITMAP 0
 #define UNDEF_FRINGE_BITMAP 1
 #define MAX_STANDARD_FRINGE_BITMAPS ARRAYELTS (standard_bitmaps)
@@ -1700,6 +3220,168 @@ Return nil if POS is not visible in WINDOW.  */)
 void
 syms_of_fringe (void)
 {
+
+
+/* *************************************************************************** */
+/* 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_reversed_vertical_bar_right_arrow, "+-reversed-vertical-bar-right-arrow");
+  Vfringe_bitmaps = Fcons (Qmc_reversed_vertical_bar_right_arrow, Vfringe_bitmaps);
+  Fput (Qmc_reversed_vertical_bar_right_arrow, Qfringe, make_fixnum (25));
+  /* (get '+-reversed-vertical-bar-right-arrow 'fringe) => 25 */
+
+  /* 26 */
+  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 (26));
+  /* (get '+-hollow-rectangle-right-arrow 'fringe) => 26 */
+
+  /* 27 */
+  DEFSYM (Qmc_reversed_hollow_rectangle_right_arrow, "+-reversed-hollow-rectangle-right-arrow");
+  Vfringe_bitmaps = Fcons (Qmc_reversed_hollow_rectangle_right_arrow, Vfringe_bitmaps);
+  Fput (Qmc_reversed_hollow_rectangle_right_arrow, Qfringe, make_fixnum (27));
+  /* (get '+-reversed-hollow-rectangle-right-arrow 'fringe) => 27 */
+
+  /* 28 */
+  DEFSYM (Qmc_hollow_rectangle, "+-hollow-rectangle");
+  Vfringe_bitmaps = Fcons (Qmc_hollow_rectangle, Vfringe_bitmaps);
+  Fput (Qmc_hollow_rectangle, Qfringe, make_fixnum (28));
+  /* (get '+-hollow-rectangle 'fringe) => 28 */
+
+  /* 29 */
+  DEFSYM (Qmc_vertical_bar, "+-vertical-bar");
+  Vfringe_bitmaps = Fcons (Qmc_vertical_bar, Vfringe_bitmaps);
+  Fput (Qmc_vertical_bar, Qfringe, make_fixnum (29));
+  /* (get '+-vertical-bar 'fringe) => 29 */
+
+  /* 30 */
+  DEFSYM (Qmc_reversed_vertical_bar, "+-reversed-vertical-bar");
+  Vfringe_bitmaps = Fcons (Qmc_reversed_vertical_bar, Vfringe_bitmaps);
+  Fput (Qmc_reversed_vertical_bar, Qfringe, make_fixnum (30));
+  /* (get '+-reversed-vertical-bar 'fringe) => 30 */
+
+  /* 31 */
+  DEFSYM (Qmc_backslash, "+-backslash");
+  Vfringe_bitmaps = Fcons (Qmc_backslash, Vfringe_bitmaps);
+  Fput (Qmc_backslash, Qfringe, make_fixnum (31));
+  /* (get '+-backslash 'fringe) => 31 */
+
+  /* 32 */
+  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 (32));
+  /* (get '+-vertical-bar-backslash 'fringe) => 32 */
+
+  /* 33 */
+  DEFSYM (Qmc_pilcrow, "+-pilcrow");
+  Vfringe_bitmaps = Fcons (Qmc_pilcrow, Vfringe_bitmaps);
+  Fput (Qmc_pilcrow, Qfringe, make_fixnum (33));
+  /* (get '+-pilcrow 'fringe) => 33 */
+
+  /* 34 */
+  DEFSYM (Qmc_smiley_face, "+-smiley-face");
+  Vfringe_bitmaps = Fcons (Qmc_smiley_face, Vfringe_bitmaps);
+  Fput (Qmc_smiley_face, Qfringe, make_fixnum (34));
+  /* (get '+-smiley-face 'fringe) => 34 */
+
+  /* 35 */
+  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 (35));
+  /* (get '+-right-single-angle 'fringe) => 35 */
+
+  /* 36 */
+  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 (36));
+  /* (get '+-left-double-angle 'fringe) => 36 */
+
+  /* 37 */
+  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 (37));
+  /* (get '+-right-double-angle 'fringe) => 37 */
+
+  /* 38 */
+  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 (38));
+  /* (get '+-left-double-angle 'fringe) => 38 */
+
+  /* 39 */
+  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 (39));
+  /* (get '+-triple-angle-right 'fringe) => 39 */
+
+  /* 40 */
+  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 (40));
+  /* (get '+-triple-angle-left 'fringe) => 40 */
+
+  /* 41 */
+  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 (41));
+  /* (get '+-single-angle-up 'fringe) => 41 */
+
+  /* 42 */
+  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 (42));
+  /* (get '+-single-angle-down 'fringe) => 42 */
+
+  /* 43 */
+  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 (43));
+  /* (get '+-double-angle-up 'fringe) => 43 */
+
+  /* 44 */
+  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 (44));
+  /* (get '+-double-angle-down 'fringe) => 44 */
+
+  /* 45 */
+  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 (45));
+  /* (get '+-triple-angle-up 'fringe) => 45 */
+
+  /* 46 */
+  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 (46));
+  /* (get '+-triple-angle-down 'fringe) => 46 */
+
+  /* 47 */
+  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 (47));
+  /* (get '+-quadruple-angle-up 'fringe) => 47 */
+
+  /* 48 */
+  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 (48));
+  /* (get '+-quadruple-angle-down 'fringe) => 48 */
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
   DEFSYM (Qtruncation, "truncation");
   DEFSYM (Qcontinuation, "continuation");
   DEFSYM (Qoverlay_arrow, "overlay-arrow");
diff --git a/src/nsterm.h b/src/nsterm.h
index 78ce608..8ef0dfe 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -660,6 +660,16 @@ typedef id instancetype;
 
 @interface EmacsScroller : NSScroller
   {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    NSRect mc_rectangle;
+
+/* *************************************************************************** */
+
+
    struct window *window;
    struct frame *frame;
    NSResponder *prevResponder;
@@ -680,6 +690,18 @@ typedef id instancetype;
    int em_whole;
    }
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+- (void)mc_set_rectangle: (NSRect)rect;
+- (NSRect)mc_get_rectangle;
+- (struct window *)mc_get_window;
+- (bool)mc_judge;
+
+/* *************************************************************************** */
+
+
 - (instancetype) initFrame: (NSRect )r window: (Lisp_Object)win;
 - (void)setFrame: (NSRect)r;
 
diff --git a/src/nsterm.m b/src/nsterm.m
index 81d36be..dfe6059 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -76,6 +76,979 @@ Updated by Christian Limpach (chris@nice.ch)
 static EmacsMenu *mainMenu;
 #endif
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+static BOOL ns_clip_to_rect (struct frame *, NSRect *, int);
+
+static void ns_reset_clipping (struct frame *);
+
+static void ns_dumpglyphs_box_or_relief (struct glyph_string *);
+
+static void ns_draw_composite_glyph_string_foreground (struct glyph_string *);
+
+static int ns_get_glyph_string_clip_rect (struct glyph_string *, NativeRectangle *);
+
+static void ns_draw_relief (NSRect, int, char, char, char, char, char, struct glyph_string *);
+
+static void ns_draw_box (NSRect, CGFloat, NSColor *, char, char);
+
+static void ns_draw_underwave (struct glyph_string *, EmacsCGFloat, EmacsCGFloat);
+
+/* Current design assumes that alpha is 1.0 */
+void
+mc_xw_color_values (struct window *w, Lisp_Object color, struct mc_RGB *lsl)
+{
+  CHECK_STRING (color);
+  NSColor * col;
+  EmacsCGFloat red, green, blue, alpha;
+  check_window_system (NULL);
+  block_input ();
+  if (ns_lisp_to_color (color, &col))
+    {
+      unblock_input ();
+      lsl->red = -1.0;
+      lsl->green = -1.0;
+      lsl->blue = -1.0;
+    }
+  [[col colorUsingDefaultColorSpace]
+        getRed: &red green: &green blue: &blue alpha: &alpha];
+  unblock_input ();
+  lsl->red = red;
+  lsl->green = green;
+  lsl->blue = blue;
+}
+
+static void
+mc_ns_draw_overwritten (struct glyph_string *s, struct glyph_matrix *matrix,
+                        struct glyph_row *row, struct glyph *cursor_glyph)
+{
+  //  int vpos = MATRIX_ROW_VPOS (row, matrix);
+  //  clock_t clock_start = clock();
+  // ns_draw_underwave (s, s->width, s->x);
+  NSColor *hollow_color = FRAME_BACKGROUND_COLOR (s->f);
+  struct face *face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
+  int vnth = MATRIX_ROW_VPOS (row, matrix);
+  /* STRETCH_GLYPH may contain more than one fake cursor at the same HPOS.
+  NOTE:  A fake cursor from one cache may overwrite a fake cursor from another
+  cache -- thus, we must check them all for overwritten fake cursors. */
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    {
+      for (int nth = 0;
+           s
+           && mc_traverse_cache_p (s->w->mc_matrix, cache_type, vnth, nth);
+           ++nth)
+        {
+          //  int x = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].x;
+          int fx = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].fx;
+          //  int y = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].y;
+          int fy = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].fy;
+          int hpos = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].hpos;
+          int vpos = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].vpos;
+          int wd = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].wd;
+          int h = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].h;
+          enum mc_cursor_type cursor_type = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_type;
+          //  int cursor_width = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_width;
+          struct mc_RGB lsl_fg = {.red = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.red,
+                                  .green = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.green,
+                                  .blue = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.blue};
+          //  struct mc_RGB lsl_bg = {.red = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.red,
+          //                          .green = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.green,
+          //                          .blue = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.blue};
+          bool active_p = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].active_p;
+          //  enum mc_flavor glyph_flavor = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph_flavor;
+          bool enabled_p = s->w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p;
+          bool go_p = (vpos == vnth
+                       && hpos == cursor_glyph->hpos
+                       && enabled_p);
+          if (!go_p)
+            continue;
+          NSRect r;
+          r.origin.x = fx;
+          r.origin.y = fy;
+          r.size.height = h;
+          r.size.width = wd;
+          [[NSColor colorWithCalibratedRed: lsl_fg.red
+                                     green: lsl_fg.green
+                                      blue: lsl_fg.blue
+                                     alpha: 1.0] set];
+      if (cursor_type == MC_FRAMED_BOX)
+        {
+          Lisp_Object buf = s->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_beg = (region_active_p) ? mc_region_limit (1) : -1;
+          ptrdiff_t region_end = (region_active_p) ? mc_region_limit (0) : -1;
+          if (region_active_p
+              && active_p
+              && cursor_glyph->charpos == region_beg)
+            {
+              enum face_id hollow_active_region_beg_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+              struct face *hollow_active_region_beg_face = FACE_FROM_ID (s->f, hollow_active_region_beg_face_id);
+              NSColor *hollow_active_region_beg_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_beg_face), s->f);
+              hollow_color = hollow_active_region_beg_color;
+            }
+            else if (region_active_p
+                     && active_p
+                     && cursor_glyph->charpos == region_end)
+              {
+                enum face_id hollow_active_region_end_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                struct face *hollow_active_region_end_face = FACE_FROM_ID (s->f, hollow_active_region_end_face_id);
+                NSColor *hollow_active_region_end_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_region_end_face), s->f);
+                hollow_color = hollow_active_region_end_color;
+              }
+              else if (region_active_p
+                       && active_p
+                       && cursor_glyph->charpos > region_beg
+                       && cursor_glyph->charpos < region_end)
+                {
+                  enum face_id hollow_active_region_between_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+                  struct face *hollow_active_region_between_face = FACE_FROM_ID (s->f, hollow_active_region_between_face_id);
+                  NSColor *hollow_active_region_between_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_between_face), s->f);
+                  hollow_color = hollow_active_region_between_color;
+                }
+                else if (active_p)
+                  {
+                    enum face_id hollow_active_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                    struct face *hollow_active_face = FACE_FROM_ID (s->f, hollow_active_face_id);
+                    NSColor *hollow_active_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_face), s->f);
+                    hollow_color = hollow_active_color;
+                  }
+                  else if (!active_p)
+                    {
+                      enum face_id hollow_inactive_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-inactive-pre-zv-face"), true);
+                      struct face *hollow_inactive_face = FACE_FROM_ID (s->f, hollow_inactive_face_id);
+                      NSColor *hollow_inactive_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_inactive_face), s->f);
+                      hollow_color = hollow_inactive_color;
+                    }
+        }
+        else if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (s->f), s->f))
+          {
+            [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f) set];
+            hollow_color = FRAME_CURSOR_COLOR (s->f);
+          }
+          switch (cursor_type)
+            {
+              case MC_NO_FRINGE_BITMAP:
+                break;
+              case MC_NO_CURSOR:
+                break;
+              case MC_RIGHT_FRINGE_BITMAP:
+              case MC_LEFT_FRINGE_BITMAP:
+              case MC_FILLED_BOX:
+                NSRectFill (r);
+                break;
+              case MC_FRAMED_BOX:
+                NSRectFill (r);
+                [hollow_color set];
+                NSRectFill (NSInsetRect (r, 1, 1));
+                [FRAME_CURSOR_COLOR (s->f) set];
+                break;
+              case MC_HOLLOW_BOX:
+                NSRectFill (r);
+                [hollow_color set];
+                NSRectFill (NSInsetRect (r, 1, 1));
+                [FRAME_CURSOR_COLOR (s->f) set];
+                break;
+              case MC_HBAR:
+                NSRectFill (r);
+                break;
+              case MC_BAR:
+                NSRectFill (r);
+                break;
+            }
+          /* If a glyph exists (s->char2b != NULL), then draw the glyph on top of the
+          newly drawn rectangle that was created hereinabove.  To the extent that we
+          want to double-imprint glyphs to make them appear to be semi-bold, it can
+          be done here for all cursor types.  The box-style cursors are imprinted
+          with glyphs only one (1) time.  The semi-bold appearance is helpful when
+          debugging to see that the coordinates are correct. */
+          if (s->char2b != NULL
+              && (cursor_type == MC_FILLED_BOX
+                  || cursor_type == MC_FRAMED_BOX
+                  || cursor_type == MC_HOLLOW_BOX))
+            {
+              BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
+              if (isComposite)
+                ns_draw_composite_glyph_string_foreground (s);
+                else
+                  {
+                    struct font *font = s->face->font;
+                    if (!font)
+                      font = FRAME_FONT (s->f);
+                    bool with_bg_p = false;
+                    font->driver->draw (s, s->cmp_from, s->nchars, s->x, s->ybase, with_bg_p);
+                  }
+            }
+        }
+    }
+  //  clock_t clock_end = clock();
+  //  double cpu_time_used = ((double) (clock_end - clock_start)) / CLOCKS_PER_SEC;
+  //  fprintf (stderr, "ns_draw_overwritten (%d):  TIME (%f)\n", vpos, cpu_time_used);
+}
+
+static void
+mc_ns_draw_window_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                  int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h,
+                  struct mc_RGB lsl, enum mc_cursor_type cursor_type,
+                  int cursor_width, enum mc_flavor glyph_flavor, bool on_p, bool active_p)
+{
+  /* The prior bug of a double imprint on the glyph where an MC_HBAR and
+  MC_BAR is placed is quite helpful to visualize errors when debugging. */
+  bool debug_p = false;
+/*
+  if (trace_redisplay_p)
+    fprintf (stderr, "mc_ns_draw_window_cursor (%s):\n\
+  x (%d) | fx (%d) | y (%d) | fy (%d) | hpos (%d) | vpos (%d)\n\
+  wd (%d) | h (%d) | RGB (%f/%f/%f)\n\
+  cursor_type (%s) | cursor_width (%d) | on_p (%s) | active_p (%s)\n\
+  glyph_flavor (%s)\n",
+  mc_window (w), x, fx, y, fy, hpos, vpos, wd, h, lsl.red, lsl.blue, lsl.green,
+  mc_cursor_type_to_string (cursor_type), cursor_width, on_p ? "y" : "n",
+  active_p ? "y" : "n", mc_flavor_to_string (glyph_flavor));
+*/
+  NSRect r, s;
+  struct frame *f = WINDOW_XFRAME (w);
+  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  struct face *face;
+  NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f);
+  /* If cursor is out of bounds, don't draw garbage.  This can happen
+     in mini-buffer windows when switching between echo area glyphs
+     and mini-buffer. */
+  if (!on_p)
+    return;
+  if (cursor_type == MC_NO_CURSOR)
+    return;
+  /* The fringe bitmaps are presently handled elsewhere, but could someday be
+  managed (in part) at this section of code. */
+  if (row->exact_window_width_line_p
+      && (row->reversed_p
+         ? (hpos < 0)
+         : (hpos >= row->used[TEXT_AREA])))
+    {
+      row->cursor_in_fringe_p = true;
+      mc_draw_fringe_bitmap (w, row, row->reversed_p, cursor_type);
+      return;
+    }
+  r.origin.x = fx;
+  r.origin.y = fy;
+  r.size.height = h;
+  r.size.width = wd;
+  /* `ns_clip_to_rect' must precede the setting of faces so as to avoid
+     unsightly gdb error messages that are next to impossible to debug:
+       Thu Mar 28 13:54:32 server.local Emacs[17207] <Error>:
+       CGContextSetFillColorWithColor: invalid context 0x0. */
+  if (!ns_clip_to_rect (f, &r, 1))
+    return;
+  face = FACE_FROM_ID (f, cursor_glyph->face_id);
+/* EXAMPLE OF HOW TO LOOK-UP A COLOR:
+     enum face_id face_id = lookup_named_face (w, f, intern ("+-bar-pre-zv-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: 1.0
+                                                   green: 1.0
+                                                    blue: 1.0
+                                                   alpha: 1.0];
+  -  ALTERNATIVE EXAMPLE:
+     enum face_id debugging_face_id = lookup_named_face (s->w, s->f, intern ("+-debugging-face"), true);
+     struct face *debugging_face = FACE_FROM_ID (s->f, debugging_face_id);
+     NSColor *color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (debugging_face), s->f);
+     [color set]; */
+  if (glyph_flavor == MC_GLYPH
+      || glyph_flavor == MC_GLYPHLESS)
+    [[NSColor colorWithCalibratedRed: lsl.red
+                               green: lsl.green
+                                blue: lsl.blue
+                               alpha: 1.0] set];
+    else
+      [FRAME_CURSOR_COLOR (f) set];
+  if (cursor_type == MC_FRAMED_BOX)
+    {
+      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_beg = (region_active_p) ? mc_region_limit (1) : -1;
+      ptrdiff_t region_end = (region_active_p) ? mc_region_limit (0) : -1;
+      if (region_active_p
+          && active_p
+          && cursor_glyph->charpos == region_beg)
+        {
+          enum face_id hollow_active_region_beg_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+          struct face *hollow_active_region_beg_face = FACE_FROM_ID (f, hollow_active_region_beg_face_id);
+          NSColor *hollow_active_region_beg_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_beg_face), f);
+          hollow_color = hollow_active_region_beg_color;
+        }
+        else if (region_active_p
+                 && active_p
+                 && cursor_glyph->charpos == region_end)
+          {
+            enum face_id hollow_active_region_end_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+            struct face *hollow_active_region_end_face = FACE_FROM_ID (f, hollow_active_region_end_face_id);
+            NSColor *hollow_active_region_end_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_region_end_face), f);
+            hollow_color = hollow_active_region_end_color;
+          }
+          else if (region_active_p
+                   && active_p
+                   && cursor_glyph->charpos > region_beg
+                   && cursor_glyph->charpos < region_end)
+            {
+              enum face_id hollow_active_region_between_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+              struct face *hollow_active_region_between_face = FACE_FROM_ID (f, hollow_active_region_between_face_id);
+              NSColor *hollow_active_region_between_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_between_face), f);
+              hollow_color = hollow_active_region_between_color;
+            }
+            else if (active_p)
+              {
+                enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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-pre-zv-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))
+      {
+        [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
+        hollow_color = FRAME_CURSOR_COLOR (f);
+      }
+#ifdef NS_IMPL_COCOA
+  NSDisableScreenUpdates ();
+#endif
+  switch (cursor_type)
+    {
+      case MC_NO_FRINGE_BITMAP:
+        break;
+      case MC_NO_CURSOR:
+        break;
+      case MC_RIGHT_FRINGE_BITMAP:
+        break;
+      case MC_LEFT_FRINGE_BITMAP:
+        break;
+      case MC_FILLED_BOX:
+        NSRectFill (r);
+        break;
+      case MC_FRAMED_BOX:
+        NSRectFill (r);
+        [hollow_color set];
+        NSRectFill (NSInsetRect (r, 1, 1));
+        [FRAME_CURSOR_COLOR (f) set];
+        break;
+      case MC_HOLLOW_BOX:
+        NSRectFill (r);
+        [hollow_color set];
+        NSRectFill (NSInsetRect (r, 1, 1));
+        [FRAME_CURSOR_COLOR (f) set];
+        break;
+      case MC_HBAR:
+        NSRectFill (r);
+        break;
+      case MC_BAR:
+        s = r;
+        /* @lawlist is focusing the initial development of feature requests
+        #17684 and #22873 on L2R languages. */
+        if (glyph_flavor != MC_GLYPH
+            && glyph_flavor != MC_GLYPHLESS)
+          {
+            /* If the character under cursor is R2L, draw the bar cursor
+               on the right of its glyph, rather than on the left. */
+            if ((cursor_glyph->resolved_level & 1) != 0)
+              s.origin.x += cursor_glyph->pixel_width - s.size.width;
+          }
+        NSRectFill (s);
+        break;
+    }
+  ns_reset_clipping (f);
+  /* draw the character under the cursor */
+  if (glyph_flavor != MC_GLYPHLESS
+      && (cursor_type == MC_FRAMED_BOX
+          || cursor_type == MC_FILLED_BOX
+          || cursor_type == MC_HOLLOW_BOX
+          || (debug_p
+              && cursor_type == MC_HBAR)
+          || (debug_p
+              && cursor_type == MC_BAR)))
+    {
+      /* `cursor_gc_p` is used only by `w32term.c` and `xterm.c'. */
+      bool cursor_gc_p = false;
+      XRectangle *saved_clip = NULL;
+      if (row->clip != NULL)
+        {
+          saved_clip = row->clip;
+          row->clip = NULL;
+        }
+      mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                            glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+      if (saved_clip != NULL)
+        row->clip = saved_clip;
+    }
+#ifdef NS_IMPL_COCOA
+  NSEnableScreenUpdates ();
+#endif
+}
+
+static void
+mc_ns_draw_text_decoration (struct glyph_string *s, struct face *face,
+                         NSColor *defaultCol, CGFloat width, CGFloat x)
+/* --------------------------------------------------------------------------
+   Draw underline, overline, and strike-through on glyph string s.
+   -------------------------------------------------------------------------- */
+{
+  if (s->for_overlaps)
+    return;
+  /* Do underline. */
+  if (face->underline_p)
+    {
+      if (s->face->underline_type == FACE_UNDER_WAVE)
+        {
+          if (face->underline_defaulted_p)
+            [defaultCol set];
+            else
+              [ns_lookup_indexed_color (face->underline_color, s->f) set];
+          ns_draw_underwave (s, width, x);
+        }
+        else if (s->face->underline_type == FACE_UNDER_LINE)
+          {
+            NSRect r;
+            unsigned long thickness, position;
+            /* If the prev was underlined, match its appearance. */
+            if (s->prev && s->prev->face->underline_p
+                && s->prev->face->underline_type == FACE_UNDER_LINE
+                && s->prev->underline_thickness > 0)
+              {
+                thickness = s->prev->underline_thickness;
+                position = s->prev->underline_position;
+              }
+              else
+                {
+                  struct font *font;
+                  unsigned long descent;
+                  font=s->font;
+                  descent = s->y + s->height - s->ybase;
+                  /* Use underline thickness of font, defaulting to 1. */
+                  thickness = (font && font->underline_thickness > 0)
+                              ? font->underline_thickness
+                              : 1;
+                  /* Determine the offset of underlining from the baseline. */
+                  if (x_underline_at_descent_line)
+                    position = descent - thickness;
+                    else if (x_use_underline_position_properties
+                             && font && font->underline_position >= 0)
+                      position = font->underline_position;
+                      else if (font)
+                        position = lround (font->descent / 2);
+                        else
+                          position = underline_minimum_offset;
+                  position = max (position, underline_minimum_offset);
+                  /* Ensure underlining is not cropped. */
+                  if (descent <= position)
+                    {
+                      position = descent - 1;
+                      thickness = 1;
+                    }
+                    else if (descent < position + thickness)
+                      thickness = 1;
+                }
+            s->underline_thickness = thickness;
+            s->underline_position = position;
+            r = NSMakeRect (x, s->ybase + position, width, thickness);
+            if (face->underline_defaulted_p)
+              [defaultCol set];
+              else
+                [ns_lookup_indexed_color (face->underline_color, s->f) set];
+            NSRectFill (r);
+          }
+    }
+  /* Do overline. We follow other terms in using a thickness of 1
+     and ignoring overline_margin. */
+  if (face->overline_p)
+    {
+      NSRect r;
+      r = NSMakeRect (x, s->y, width, 1);
+      if (face->overline_color_defaulted_p)
+        [defaultCol set];
+        else
+          [ns_lookup_indexed_color (face->overline_color, s->f) set];
+      NSRectFill (r);
+    }
+  /* Do strike-through.  We follow other terms for thickness and
+     vertical position.*/
+  if (face->strike_through_p)
+    {
+      NSRect r;
+      unsigned long dy;
+      dy = lrint ((s->height - 1) / 2);
+      r = NSMakeRect (x, s->y + dy, width, 1);
+      if (face->strike_through_color_defaulted_p)
+        [defaultCol set];
+        else
+          [ns_lookup_indexed_color (face->strike_through_color, s->f) set];
+      NSRectFill (r);
+    }
+}
+
+static void
+mc_ns_dumpglyphs_stretch (struct glyph_string *s, struct glyph_matrix *matrix,
+                          struct glyph_row *row, int wd)
+{
+  NSRect r[2];
+  int n, i;
+  struct face *face;
+  NSColor *fgCol, *bgCol;
+  if (!s->background_filled_p)
+    {
+      n = ns_get_glyph_string_clip_rect (s, r);
+      *r = NSMakeRect (s->x, s->y, s->background_width, s->height);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      if (s->hl == DRAW_MOUSE_FACE)
+        {
+          face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
+          if (!face)
+            face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+        }
+        else
+         face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+      bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
+      fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+      for (i = 0; i < n; ++i)
+        {
+          if (!s->row->full_width_p)
+            {
+              int overrun, leftoverrun;
+              /* truncate to avoid overwriting fringe and/or scrollbar */
+              overrun = max (0, (s->x + s->background_width)
+                                 - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
+                              - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
+                    r[i].size.width -= overrun;
+              /* truncate to avoid overwriting to left of the window box */
+              leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w)
+                             + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x;
+              if (leftoverrun > 0)
+                {
+                  r[i].origin.x += leftoverrun;
+                  r[i].size.width -= leftoverrun;
+                }
+              /* XXX: Try to work between problem where a stretch glyph on
+                 a partially-visible bottom row will clear part of the
+                 modeline, and another where list-buffers headers and similar
+                 rows erroneously have visible_height set to 0.  Not sure
+                 where this is coming from as other terms seem not to show. */
+              r[i].size.height = min (s->height, s->row->visible_height);
+            }
+          [bgCol set];
+          /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
+             overwriting cursor (usually when cursor on a tab) */
+          if (s->hl == DRAW_CURSOR)
+            {
+              /* FIXME:  Do we still need to prevent this section of code from
+              erasing the fake MC_HBAR that extends the entire length of the
+              STRETCH_GLYPH?  This may have been done prior to the fix relating
+              to left/right overwritten glyphs. */
+              r[i].size.height -= 1;
+              //  enum face_id debugging_face_id = lookup_named_face (s->w, s->f, intern ("+-debugging-face"), true);
+              //  struct face *debugging_face = FACE_FROM_ID (s->f, debugging_face_id);
+              //  NSColor *color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (debugging_face), s->f);
+              //  [color set];
+              CGFloat x = r[i].origin.x;
+              CGFloat width = wd;
+              r[i].size.width -= width;
+              r[i].origin.x += width;
+              NSRectFill (r[i]);
+              /* Draw overlining, etc. on the cursor. */
+              if (s->w->phys_cursor_type == MC_FILLED_BOX)
+                mc_ns_draw_text_decoration (s, face, bgCol, width, x);
+                else
+                  mc_ns_draw_text_decoration (s, face, fgCol, width, x);
+            }
+          else
+            {
+  //  int rx = r[i].origin.x;
+  //  int ry = r[i].origin.y;
+  //  int rw = r[i].size.width;
+  //  int rh = r[i].size.height;
+  //  fprintf (stderr, "mc_ns_dumpglyphs_stretch:  vpos (%d) | rx (%d) | ry (%d) | rw (%d) | rh (%d)\n",
+  //                   s->first_glyph->vpos, rx, ry, rw, rh);
+              NSRectFill (r[i]);
+            }
+          /* Draw overlining, etc. on the stretch glyph (or the part
+             of the stretch glyph after the cursor). */
+          mc_ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
+                                      r[i].origin.x);
+        }
+      if ((s->left_overwritten_p || s->right_overwritten_p)
+          && (s->action_type == MC_DRAW_GLYPH_STRING|| s->action_type == MC_ERASE_GLYPH_STRING))
+        mc_ns_draw_overwritten (s, matrix, row, s->first_glyph);
+      ns_reset_clipping (s->f);
+      s->background_filled_p = 1;
+    }
+}
+
+static void
+mc_ns_dumpglyphs_image (struct glyph_string *s, NSRect r, struct mc_RGB lsl,
+                        enum mc_flavor glyph_flavor, enum mc_cursor_type cursor_type,
+                        bool active_p)
+/* --------------------------------------------------------------------------
+      Renders an image and associated borders.
+   -------------------------------------------------------------------------- */
+{
+  EmacsImage *img = s->img->pixmap;
+  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int x = s->x, y = s->ybase - image_ascent (s->img, s->face, &s->slice);
+  int bg_x, bg_y, bg_height;
+  int th;
+  char raised_p;
+  NSRect br;
+  struct face *face;
+  NSColor *tdCol;
+  NSTRACE ("mc_ns_dumpglyphs_image");
+  if (s->face->box != FACE_NO_BOX
+      && s->first_glyph->left_box_line_p && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
+  bg_x = x;
+  bg_y =  s->slice.y == 0 ? s->y : s->y + box_line_vwidth;
+  bg_height = s->height;
+  /* other terms have this, but was causing problems w/tabbar mode */
+  /* - 2 * box_line_vwidth; */
+  if (s->slice.x == 0) x += s->img->hmargin;
+  if (s->slice.y == 0) y += s->img->vmargin;
+  /* Draw BG: if we need larger area than image itself cleared, do that,
+     otherwise, since we composite the image under NS (instead of mucking
+     with its background color), we must clear just the image area. */
+  if (s->hl == DRAW_MOUSE_FACE)
+    {
+      face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
+      if (!face)
+        face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+    }
+  else
+    face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+  [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
+  if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
+      || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
+    {
+      br = NSMakeRect (bg_x, bg_y, s->background_width, bg_height);
+      s->background_filled_p = 1;
+    }
+    else
+      br = NSMakeRect (x, y, s->slice.width, s->slice.height);
+  NSRectFill (br);
+  /* Draw the image.. do we need to draw placeholder if img ==nil? */
+  if (img != nil)
+    {
+#ifdef NS_IMPL_COCOA
+      NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height);
+      NSRect ir = NSMakeRect (s->slice.x, s->slice.y,
+                              s->slice.width, s->slice.height);
+      [img drawInRect: dr
+             fromRect: ir
+             operation: NSCompositeSourceOver
+              fraction: 1.0
+           respectFlipped: YES
+                hints: nil];
+#else
+      [img compositeToPoint: NSMakePoint (x, y + s->slice.height)
+                  operation: NSCompositeSourceOver];
+#endif
+    }
+  if (s->hl == DRAW_CURSOR)
+    {
+      [FRAME_CURSOR_COLOR (s->f) set];
+      if (s->w->phys_cursor_type == MC_FILLED_BOX)
+        tdCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
+        else
+          /* Currently on NS img->mask is always 0. Since
+             get_window_cursor_type specifies a hollow box cursor when on
+             a non-masked image we never reach this clause. But we put it
+             in in anticipation of better support for image masks on NS. */
+          tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+    }
+    else
+      tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+  /* Draw underline, overline, strike-through. */
+  mc_ns_draw_text_decoration (s, face, tdCol, br.size.width, br.origin.x);
+  /* Draw relief, if requested */
+  if (s->img->relief || s->hl ==DRAW_IMAGE_RAISED || s->hl ==DRAW_IMAGE_SUNKEN)
+    {
+      if (s->hl == DRAW_IMAGE_SUNKEN || s->hl == DRAW_IMAGE_RAISED)
+        {
+          th = tool_bar_button_relief >= 0 ?
+            tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
+          raised_p = (s->hl == DRAW_IMAGE_RAISED);
+        }
+        else
+          {
+            th = abs (s->img->relief);
+            raised_p = (s->img->relief > 0);
+          }
+      r.origin.x = x - th;
+      r.origin.y = y - th;
+      r.size.width = s->slice.width + 2*th-1;
+      r.size.height = s->slice.height + 2*th-1;
+      ns_draw_relief (r, th, raised_p,
+                      s->slice.y == 0,
+                      s->slice.y + s->slice.height == s->img->height,
+                      s->slice.x == 0,
+                      s->slice.x + s->slice.width == s->img->width, s);
+    }
+  /* If there is no mask, the background won't be seen,
+     so draw a rectangle on the image for the cursor.
+     Do this for all images, getting transparency right is not reliable. */
+  if (s->hl == DRAW_CURSOR)
+    {
+      int thickness = abs (s->img->relief);
+      if (thickness == 0) thickness = 1;
+    if (glyph_flavor == MC_GLYPH
+        || glyph_flavor == MC_GLYPHLESS)
+      {
+        NSColor *border_color = [NSColor colorWithCalibratedRed: lsl.red
+                                                          green: lsl.green
+                                                           blue: lsl.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);
+    }
+}
+
+static void
+mc_ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
+{
+  NSTRACE ("mc_ns_maybe_dumpglyphs_background");
+  if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/)
+    {
+      int box_line_width = max (s->face->box_line_width, 0);
+      if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
+          /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
+             dimensions, since the actual glyphs might be much
+             smaller.  So in that case we always clear the rectangle
+             with background color. */
+          || FONT_TOO_HIGH (s->font)
+          || s->font_not_found_p || s->extends_to_end_of_line_p || force_p)
+        {
+          struct face *face;
+          if (s->hl == DRAW_MOUSE_FACE)
+            {
+              face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
+              if (!face)
+                face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+            }
+            else
+              face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+          if (!face->stipple)
+            [(NS_FACE_BACKGROUND (face) != 0
+              ? ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f)
+              : FRAME_BACKGROUND_COLOR (s->f)) set];
+            else
+              {
+                struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
+                [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
+              }
+          if (s->hl != DRAW_CURSOR)
+            {
+              s->rectangle_nuked_p = true;
+              NSRect r = NSMakeRect (s->x, s->y + box_line_width,
+                                    s->background_width,
+                                    s->height-2*box_line_width);
+              NSRectFill (r);
+            }
+          s->background_filled_p = 1;
+        }
+    }
+}
+
+static void
+mc_ns_draw_glyph_string (struct glyph_string *s, struct glyph_matrix *matrix, struct glyph_row *row,
+                         struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+                         enum mc_cursor_type cursor_type,
+                         int wd, bool active_p, bool cursor_gc_p)
+/* --------------------------------------------------------------------------
+      External (RIF): Main draw-text call.
+   -------------------------------------------------------------------------- */
+{
+  NSRect r[2];
+  int n;
+  char box_drawn_p = 0;
+  struct font *font = s->face->font;
+  if (!font)
+    font = FRAME_FONT (s->f);
+  NSTRACE_WHEN (NSTRACE_GROUP_GLYPHS, "mc_ns_draw_glyph_string");
+  if (s->next && s->right_overhang && !s->for_overlaps)
+    {
+      int width;
+      struct glyph_string *next;
+      for (width = 0, next = s->next;
+           next && width < s->right_overhang;
+           width += next->width, next = next->next)
+        if (next->first_glyph->type != IMAGE_GLYPH)
+          {
+            if (next->first_glyph->type != STRETCH_GLYPH)
+              {
+                n = ns_get_glyph_string_clip_rect (s->next, r);
+                if (!ns_clip_to_rect (s->f, r, n))
+                  return;
+                mc_ns_maybe_dumpglyphs_background (s->next, 1);
+                ns_reset_clipping (s->f);
+              }
+              else
+                mc_ns_dumpglyphs_stretch (s->next, matrix, row, wd);
+            next->num_clips = 0;
+          }
+    }
+  if (!s->for_overlaps && s->face->box != FACE_NO_BOX
+      && (s->first_glyph->type == CHAR_GLYPH
+          || s->first_glyph->type == COMPOSITE_GLYPH))
+    {
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      mc_ns_maybe_dumpglyphs_background (s, 1);
+      ns_dumpglyphs_box_or_relief (s);
+      ns_reset_clipping (s->f);
+      box_drawn_p = 1;
+    }
+  switch (s->first_glyph->type)
+    {
+    case IMAGE_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      mc_ns_dumpglyphs_image (s, r[0], lsl, glyph_flavor, cursor_type, active_p);
+      ns_reset_clipping (s->f);
+      break;
+    case STRETCH_GLYPH:
+      mc_ns_dumpglyphs_stretch (s, matrix, row, wd);
+      break;
+    case CHAR_GLYPH:
+    case COMPOSITE_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      if (s->for_overlaps
+          || (s->cmp_from > 0
+              && ! s->first_glyph->u.cmp.automatic))
+        s->background_filled_p = 1;
+        else
+          mc_ns_maybe_dumpglyphs_background (s, s->first_glyph->type == COMPOSITE_GLYPH);
+      int flags = (s->hl == DRAW_CURSOR)
+                    ? NS_DUMPGLYPH_CURSOR
+                  : (s->hl == DRAW_MOUSE_FACE)
+                    ? NS_DUMPGLYPH_MOUSEFACE
+                  : (s->for_overlaps)
+                    ? NS_DUMPGLYPH_FOREGROUND
+                  : NS_DUMPGLYPH_NORMAL;
+      unsigned long saved_fg = NS_FACE_FOREGROUND (s->face);
+      if (s->hl == DRAW_CURSOR && cursor_type == MC_FILLED_BOX)
+        {
+          unsigned long tmp = NS_FACE_BACKGROUND (s->face);
+          NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
+          NS_FACE_FOREGROUND (s->face) = tmp;
+        }
+        else if (s->hl == DRAW_CURSOR
+                 && cursor_type == MC_FRAMED_BOX
+                 && active_p)
+          {
+            enum face_id hollow_active_face_id =
+              lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+            struct face *hollow_active_face = FACE_FROM_ID (s->f, hollow_active_face_id);
+            NS_FACE_FOREGROUND (s->face) = NS_FACE_FOREGROUND (hollow_active_face);
+          }
+          else if (s->hl == DRAW_CURSOR
+                   && cursor_type == MC_FRAMED_BOX
+                   && active_p)
+            {
+              enum face_id hollow_inactive_face_id =
+                lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-inactive-pre-zv-face"), true);
+              struct face *hollow_inactive_face = FACE_FROM_ID (s->f, hollow_inactive_face_id);
+              NS_FACE_FOREGROUND (s->face) = NS_FACE_FOREGROUND (hollow_inactive_face);
+            }
+      if (s->first_glyph->type == COMPOSITE_GLYPH)
+        ns_draw_composite_glyph_string_foreground (s);
+        else
+          {
+            bool with_bg_p = ((flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
+                              || flags == NS_DUMPGLYPH_MOUSEFACE);
+            if (with_bg_p)
+              s->background_nuked_p = true;
+            font->driver->draw (s, s->cmp_from, s->nchars, s->x, s->ybase, with_bg_p);
+          }
+      NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
+                     ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), s->f)
+                     : FRAME_FOREGROUND_COLOR (s->f));
+      [col set];
+      /* Draw underline, overline, strike-through. */
+      mc_ns_draw_text_decoration (s, s->face, col, s->width, s->x);
+      if (s->first_glyph->type != COMPOSITE_GLYPH
+          && (s->left_overwritten_p || s->right_overwritten_p)
+          && (s->background_nuked_p || s->rectangle_nuked_p)
+          && (s->action_type == MC_DRAW_GLYPH_STRING|| s->action_type == MC_ERASE_GLYPH_STRING))
+        mc_ns_draw_overwritten (s, matrix, row, s->first_glyph);
+      if (s->hl == DRAW_CURSOR
+          && cursor_type == MC_FILLED_BOX)
+        {
+          unsigned long tmp = NS_FACE_BACKGROUND (s->face);
+          NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
+          NS_FACE_FOREGROUND (s->face) = tmp;
+        }
+        else if (s->hl == DRAW_CURSOR
+                 && cursor_type == MC_FRAMED_BOX)
+          NS_FACE_FOREGROUND (s->face) = saved_fg;
+      ns_reset_clipping (s->f);
+      break;
+    case GLYPHLESS_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      if (s->for_overlaps
+          || (s->cmp_from > 0
+              && ! s->first_glyph->u.cmp.automatic))
+        s->background_filled_p = 1;
+      else
+        mc_ns_maybe_dumpglyphs_background (s, s->first_glyph->type == COMPOSITE_GLYPH);
+      ns_reset_clipping (s->f);
+      break;
+    default:
+      emacs_abort ();
+    }
+  /* Draw box if not done already. */
+  if (!s->for_overlaps
+      && !box_drawn_p
+      && s->face->box != FACE_NO_BOX)
+    {
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!ns_clip_to_rect (s->f, r, n))
+        return;
+      ns_dumpglyphs_box_or_relief (s);
+      ns_reset_clipping (s->f);
+    }
+  s->num_clips = 0;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* ==========================================================================
 
    NSTRACE, Trace support.
@@ -1109,6 +2082,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);
 
@@ -1209,6 +2192,16 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
 
 /*   if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
   MOUSE_HL_INFO (f)->mouse_face_defer = 0;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  f->mc_updating_frame = NULL;
+
+/* *************************************************************************** */
+
+
 }
 
 
@@ -4803,6 +5796,17 @@ in certain situations (rapid incoming events).
       bar = [[EmacsScroller alloc] initFrame: r window: win];
       wset_vertical_scroll_bar (window, make_mint_ptr (bar));
       update_p = YES;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      /* This is only for debugging purposes. */
+      [bar mc_set_rectangle: r];
+
+/* *************************************************************************** */
+
+
     }
   else
     {
@@ -4810,12 +5814,30 @@ in certain situations (rapid incoming events).
       bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
       oldRect = [bar frame];
       r.size.width = oldRect.size.width;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
       if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
         {
+          /* The main window has probably been resized.  Graciously delete the
+          old scroll bar without repainting its rectangle; and, create a new
+          scroll bar elsewhere.*/
           if (oldRect.origin.x != r.origin.x)
+            {
               ns_clear_frame_area (f, left, top, width, height);
+              [bar mc_judge];
+              bar = [[EmacsScroller alloc] initFrame: r window: win];
+              wset_vertical_scroll_bar (window, make_mint_ptr (bar));
+            }
+            else
           [bar setFrame: r];
         }
+
+/* *************************************************************************** */
+
+
     }
 
   if (update_p)
@@ -4975,9 +5997,57 @@ in certain situations (rapid incoming events).
     {
       view = [subviews objectAtIndex: i];
       if (![view isKindOfClass: [EmacsScroller class]]) continue;
-      if ([view judge])
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  /* `XSETWINDOW' will sometimes cause Emacs to crash when running under gdb even
+  though (w != NULL).  Therefore, we cannot reliably use `WINDOW_LIVE_P'. */
+  struct window *w = [view mc_get_window];
+  if (w != NULL
+      && NILP (w->contents))
+    {
+      BOOL debug_p = false;
+      if (debug_p
+          /* `window_box' calls `window_box_height', which will cause Emacs to
+          crash if FRAMEP (w->frame) is not satisfied. */
+          && FRAMEP (w->frame))
+        {
+          NSRect r0 = [view mc_get_rectangle];
+          int x0 = NSMinX (r0);
+          int y0 = NSMinY (r0);
+          int wd0 = NSWidth (r0);
+          int h0 = NSHeight (r0);
+          int window_y, window_height;
+          window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
+          int top = window_y;
+          int height = window_height;
+          int width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
+          int left = WINDOW_SCROLL_BAR_AREA_X (w);
+          NSRect r1 = NSMakeRect (left, top, width, height);
+          /* The parent view is flipped, so we need to flip y value. */
+          EmacsView *frame_view = FRAME_NS_VIEW (f);
+          NSRect v = [frame_view frame];
+          r1.origin.y = (v.size.height - r1.size.height - r1.origin.y);
+          int x1 = NSMinX (r1);
+          int y1 = NSMinY (r1);
+          int wd1 = NSWidth (r1);
+          int h1 = NSHeight (r1);
+          fprintf (stderr, "%s -- DEAD:\n\
+          x0/x1 (%d/%d) | y0/y1 (%d/%d) | wd0/wd1 (%d/%d) | h0/h1 (%d/%d)\n",
+          mc_window (w), x0, x1, y0, y1, wd0, wd1, h0, h1);
+        }
+      if ([view mc_judge])
         removed = YES;
     }
+    else if ([view judge])
+      removed = YES;
+
+/* *************************************************************************** */
+
+
+    }
 
   if (removed)
     [eview updateFrameSize: NO];
@@ -5106,6 +6176,20 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
 extern frame_parm_handler ns_frame_parm_handlers[];
 static struct redisplay_interface ns_redisplay_interface =
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* `redisplay_interface' in `nsterm.m` must be in the exact same order as the
+`redisplay_interface' in `dispextern.h`! */
+
+  mc_ns_draw_window_cursor,
+  mc_ns_draw_glyph_string,
+
+/* *************************************************************************** */
+
+
   ns_frame_parm_handlers,
   x_produce_glyphs,
   x_write_glyphs,
@@ -8721,6 +9805,49 @@ - (BOOL)canBecomeMainWindow
 
 @implementation EmacsScroller
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+- (void)mc_set_rectangle: (NSRect)rect
+{
+  mc_rectangle = rect;
+}
+
+- (NSRect)mc_get_rectangle
+{
+  return mc_rectangle;
+}
+
+- (struct window *)mc_get_window
+{
+  return window;
+}
+
+- (bool)mc_judge
+{
+  NSTRACE ("[EmacsScroller mc_judge]");
+  bool ret = condemned;
+  block_input ();
+  if (condemned)
+    {
+      /* ensure other scrollbar updates after deletion */
+      EmacsView *view = (EmacsView *)FRAME_NS_VIEW (frame);
+      if (view != nil)
+        view->scrollbarsNeedingUpdate++;
+    }
+  if (window)
+    wset_vertical_scroll_bar (window, Qnil);
+  window = 0;
+  [self removeFromSuperviewWithoutNeedingDisplay];
+  [self release];
+  unblock_input ();
+  return ret;
+}
+
+/* *************************************************************************** */
+
+
 /* for repeat button push */
 #define SCROLL_BAR_FIRST_DELAY 0.5
 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
diff --git a/src/pdumper.c b/src/pdumper.c
index cb2915c..36d8bfe 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2770,7 +2770,7 @@ dump_hash_table (struct dump_context *ctx,
 static dump_off
 dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
 {
-#if CHECK_STRUCTS && !defined HASH_buffer_E34A11C6B9
+#if CHECK_STRUCTS && !defined HASH_buffer_A9CF81FED4
 # error "buffer changed. See CHECK_STRUCTS comment."
 #endif
   struct buffer munged_buffer = *in_buffer;
diff --git a/src/w32term.c b/src/w32term.c
index bb1f0ba..62b1baa 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -62,6 +62,878 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "bitmaps/gray.xbm"
 #endif
 
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+#ifdef GLYPH_DEBUG
+static void x_check_font (struct frame *, struct font *);
+#endif
+
+static void XChangeGC (void *, XGCValues *, unsigned long, XGCValues *);
+
+static void w32_draw_underwave (struct glyph_string *, COLORREF);
+
+static void x_set_mode_line_face_gc (struct glyph_string *);
+
+static void x_set_mouse_face_gc (struct glyph_string *);
+
+static void w32_clip_to_row (struct window *, struct glyph_row *, enum glyph_row_area, HDC);
+
+static void w32_set_clip_rectangle (HDC, RECT *);
+
+static void x_set_glyph_string_gc (struct glyph_string *);
+
+static void x_set_glyph_string_clipping (struct glyph_string *);
+
+static void x_draw_glyph_string_bg_rect (struct glyph_string *, int, int, int, int);
+
+static void x_draw_glyph_string_background (struct glyph_string *, bool);
+
+static void x_draw_glyph_string_box (struct glyph_string *);
+
+static void x_set_glyph_string_clipping_exactly (struct glyph_string *, struct glyph_string *);
+
+static void x_draw_image_glyph_string (struct glyph_string *);
+
+static void x_draw_glyph_string_foreground (struct glyph_string *);
+
+static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
+
+static void x_draw_glyphless_glyph_string_foreground (struct glyph_string *);
+
+void
+mc_xw_color_values (struct window *w, Lisp_Object color, struct mc_RGB *lsl)
+{
+  CHECK_STRING (color);
+  XColor temp;
+  struct frame *f = decode_window_system_frame (w->frame);
+  if (w32_defined_color (f, SSDATA (color), &temp, false))
+    {
+      lsl->red = ((GetRValue (temp.pixel) << 8) | GetRValue (temp.pixel)) / 65535.0;
+      lsl->green = ((GetGValue (temp.pixel) << 8) | GetGValue (temp.pixel)) / 65535.0;
+      lsl->blue = ((GetBValue (temp.pixel) << 8) | GetBValue (temp.pixel)) / 65535.0;
+    }
+  else
+    {
+      lsl->red = -1.0;
+      lsl->green = -1.0;
+      lsl->blue = -1.0;
+    }
+}
+
+/* Draw stretch glyph string S.  */
+static void
+mc_w32_draw_stretch_glyph_string (struct glyph_string *s)
+{
+  eassert (s->first_glyph->type == STRETCH_GLYPH);
+  if (s->hl == DRAW_CURSOR
+      && !x_stretch_cursor_p)
+    {
+      /* If `x-stretch-cursor' is nil, don't draw a block cursor as
+   wide as the stretch glyph.  */
+      int width, background_width = s->background_width;
+      int x = s->x;
+      if (!s->row->reversed_p)
+        {
+          int left_x = window_box_left_offset (s->w, TEXT_AREA);
+          if (x < left_x)
+            {
+              background_width -= left_x - x;
+              x = left_x;
+            }
+        }
+       else
+        {
+          /* In R2L rows, draw the cursor on the right edge of the
+             stretch glyph.  */
+          int right_x = window_box_right (s->w, TEXT_AREA);
+          if (x + background_width > right_x)
+            background_width -= x - right_x;
+          x += background_width;
+        }
+      width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+      if (s->row->reversed_p)
+        x -= width;
+      /* Draw cursor.  */
+      x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
+      /* Clear rest using the GC of the original non-cursor face.  */
+      if (width < background_width)
+        {
+          XGCValues *gc = s->face->gc;
+          int y = s->y;
+          int w = background_width - width, h = s->height;
+          RECT r;
+                HDC hdc = s->hdc;
+          if (!s->row->reversed_p)
+            x += width;
+          else
+            x = s->x;
+          if (s->row->mouse_face_p
+              && cursor_in_mouse_face_p (s->w))
+            {
+              x_set_mouse_face_gc (s);
+              gc = s->gc;
+            }
+          else
+            gc = s->face->gc;
+          get_glyph_string_clip_rect (s, &r);
+          w32_set_clip_rectangle (hdc, &r);
+#if 0 /* TODO: stipple */
+          if (s->face->stipple)
+            {
+              /* Fill background with a stipple pattern.  */
+              XSetFillStyle (s->display, gc, FillOpaqueStippled);
+              XFillRectangle (s->display, s->window, gc, x, y, w, h);
+              XSetFillStyle (s->display, gc, FillSolid);
+            }
+          else
+#endif
+            {
+              w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
+            }
+        }
+    }
+  else if (!s->background_filled_p)
+    {
+      int background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+      /* Don't draw into left margin, fringe or scrollbar area
+         except for header line and mode line.  */
+      if (x < left_x && !s->row->mode_line_p)
+        {
+          background_width -= left_x - x;
+          x = left_x;
+        }
+      if (background_width > 0)
+        x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+    }
+  s->background_filled_p = true;
+}
+
+/* Set S->gc to a suitable GC for drawing glyph string S in cursor
+   face.  */
+static void
+mc_w32_set_cursor_gc (struct glyph_string *s, bool cursor_gc_p)
+{
+  if (cursor_gc_p)
+    {
+      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)
+      /* Sometimes we are not called for each change in the default
+      face's background color (e.g., bug#26851), so the additional
+      test in the next line gives us a chance to resync.  */
+      && s->f->output_data.w32->cursor_gc->foreground == s->face->background
+      && !s->cmp)
+    s->gc = s->f->output_data.w32->cursor_gc;
+  else
+    {
+      /* Cursor on non-default face: must merge.  */
+      XGCValues xgcv;
+      unsigned long mask;
+      xgcv.background = s->f->output_data.w32->cursor_pixel;
+      xgcv.foreground = s->face->background;
+      /* If the glyph would be invisible, try a different foreground.  */
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->face->foreground;
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->face->foreground;
+      /* Make sure the cursor is distinct from text in this face.  */
+      if (xgcv.background == s->face->background
+          && xgcv.foreground == s->face->foreground)
+        {
+          xgcv.background = s->face->foreground;
+          xgcv.foreground = s->face->background;
+        }
+      IF_DEBUG (x_check_font (s->f, s->font));
+      xgcv.font = s->font;
+      mask = GCForeground | GCBackground | GCFont;
+      if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
+        XChangeGC (NULL, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc, mask, &xgcv);
+      else
+        FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
+          = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &xgcv);
+      s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
+    }
+}
+
+/* Set S->gc of glyph string S for drawing that glyph string.  Set
+   S->stippled_p to a non-zero value if the face of S has a stipple pattern. */
+static inline void
+mc_w32_set_glyph_string_gc (struct glyph_string *s, bool cursor_gc_p)
+{
+  prepare_face_for_display (s->f, s->face);
+  if (s->hl == DRAW_NORMAL_TEXT)
+    {
+      s->gc = s->face->gc;
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_INVERSE_VIDEO)
+    {
+      x_set_mode_line_face_gc (s);
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_CURSOR)
+    {
+      mc_w32_set_cursor_gc (s, cursor_gc_p);
+      s->stippled_p = false;
+    }
+  else if (s->hl == DRAW_MOUSE_FACE)
+    {
+      x_set_mouse_face_gc (s);
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_IMAGE_RAISED
+           || s->hl == DRAW_IMAGE_SUNKEN)
+    {
+      s->gc = s->face->gc;
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else
+    emacs_abort ();
+  /* GC must have been set.  */
+  eassert (s->gc != 0);
+}
+
+/* Draw a hollow box cursor on window W in glyph row ROW.  */
+static void
+mc_w32_draw_hollow_cursor (struct window *w, struct glyph_matrix *matrix,
+                           struct glyph_row *row, int x, int fx, int y, int fy,
+                           int hpos, int vpos, int wd, int h)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  HDC hdc;
+  RECT rect;
+  HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
+  /* Get the glyph the cursor is on.  If we can't tell because
+     the current matrix is invalid or such, give up.  */
+  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  if (cursor_glyph == NULL)
+    {
+      DeleteObject (hb);
+      return;
+    }
+  int rl = fx;
+  int rt = fy;
+  int rr = rl + wd;
+  int rb = rt + h;
+/*
+  fprintf (stderr, "MC_HOLLOW_BOX:  rl (%d) | rt (%d) | rr (%d) | rb (%d)\n", rl, rt, rr, rb);
+*/
+  rect.left = rl;
+  rect.top = rt;
+  rect.right = rr;
+  rect.bottom = rb;
+  hdc = get_frame_dc (f);
+  /* Set clipping, draw the rectangle, and reset clipping again.  */
+  w32_clip_to_row (w, row, TEXT_AREA, hdc);
+  FrameRect (hdc, &rect, hb);
+  DeleteObject (hb);
+  w32_set_clip_rectangle (hdc, NULL);
+  release_frame_dc (f, hdc);
+}
+
+/* Draw a bar cursor on window W in glyph row ROW. */
+static void
+mc_w32_draw_bar_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+  int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h, int width,
+  enum mc_cursor_type kind, bool cursor_gc_invisible_okay_p)
+{
+  struct frame *f = XFRAME (w->frame);
+  /* If cursor is out of bounds, don't draw garbage.  This can happen
+     in mini-buffer windows when switching between echo area glyphs
+     and mini-buffer.  */
+  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  if (cursor_glyph == NULL)
+    return;
+  /* If on an image, draw like a normal cursor.  That's usually better
+     visible than drawing a bar, esp. if the image is large so that
+     the bar might not be in the window.  */
+  if (cursor_glyph->type == IMAGE_GLYPH)
+    {
+      struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+      enum mc_flavor glyph_flavor = NO_FLAVOR;
+      enum mc_cursor_type cursor_type = MC_HOLLOW_BOX;
+      bool active_p = false;
+      bool cursor_gc_p = false;
+      mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                            glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+    }
+  else
+    {
+      COLORREF cursor_color = f->output_data.w32->cursor_pixel;
+      struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+      HDC hdc;
+      /* If the glyph's background equals the color we normally draw
+      the bar cursor in, the bar cursor in its normal color is
+      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
+          && !cursor_gc_invisible_okay_p)
+        cursor_color = face->foreground;
+      int default_fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+      hdc = get_frame_dc (f);
+      w32_clip_to_row (w, row, TEXT_AREA, hdc);
+      int rx = fx;
+      int ry = fy;
+      int rw = wd;
+      int rh = h;
+/*
+    fprintf (stderr, "MC_HBAR:  fx (%d) | fy (%d) | wd (%d) | h (%d)\n", rx, ry, rw, rh);
+*/
+      w32_fill_area (f, hdc, cursor_color, rx, ry, rw, rh);
+      w32_set_clip_rectangle (hdc, NULL);
+      release_frame_dc (f, hdc);
+    }
+}
+
+/* RIF: Draw or clear cursor on window W.  */
+static void
+mc_w32_draw_window_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                  int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h,
+                  struct mc_RGB lsl, enum mc_cursor_type cursor_type,
+                  int cursor_width, enum mc_flavor glyph_flavor, bool on_p, bool active_p)
+{
+  if (on_p)
+    {
+      /* If this is the active cursor, we need to track it with the
+      system caret, so third party software like screen magnifiers
+      and speech synthesizers can follow the cursor.  */
+      if (active_p)
+        {
+          struct frame *f = XFRAME (WINDOW_FRAME (w));
+          HWND hwnd = FRAME_W32_WINDOW (f);
+          w32_system_caret_x
+            = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+          /* FIXME:  What should we use instead of `w->phys_cursor_ascent'? */
+          w32_system_caret_y
+            = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
+               + row->ascent - w->phys_cursor_ascent);
+          w32_system_caret_window = w;
+          w32_system_caret_hdr_height = WINDOW_HEADER_LINE_HEIGHT (w);
+          w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w);
+          PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
+          /* If the size of the active cursor changed, destroy the old
+             system caret.  */
+          if (w32_system_caret_hwnd
+              && (w32_system_caret_height != h))
+            PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
+          w32_system_caret_height = h;
+          /* Move the system caret.  */
+          PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
+        }
+      /* The fringe bitmaps are presently handled elsewhere, but could someday
+      be managed (in part) at this section of code. */
+      if (row->exact_window_width_line_p
+          && (row->reversed_p
+             ? (hpos < 0)
+             : (hpos >= row->used[TEXT_AREA])))
+        {
+          row->cursor_in_fringe_p = true;
+          mc_draw_fringe_bitmap (w, row, row->reversed_p, cursor_type);
+          return;
+        }
+  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;
+  /* On Windows, RGB values are 0-255, not 0-65535. */
+  int red = min (255, 255 * lsl.red);
+  int green = min (255, 255 * lsl.green);
+  int blue = min (255, 255 * lsl.blue);
+  COLORREF color_pixel = PALETTERGB (red, green, blue);
+  switch (cursor_type)
+  {
+    case MC_NO_FRINGE_BITMAP:
+      break;
+    case MC_NO_CURSOR:
+      break;
+    case MC_RIGHT_FRINGE_BITMAP:
+      break;
+    case MC_LEFT_FRINGE_BITMAP:
+      break;
+    case MC_FRAMED_BOX:
+    {
+      struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+      if (cursor_glyph == NULL)
+        return;
+      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_beg = (region_active_p) ? mc_region_limit (1) : -1;
+      ptrdiff_t region_end = (region_active_p) ? mc_region_limit (0) : -1;
+      if (cursor_glyph->type != IMAGE_GLYPH && lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in w32fns.c.  */
+          if (region_active_p
+              && active_p
+              && cursor_glyph->charpos == region_beg)
+            {
+              enum face_id hollow_active_region_beg_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+              struct face *hollow_active_region_beg_face = FACE_FROM_ID (f, hollow_active_region_beg_face_id);
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+              struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+              gc_values.foreground = hollow_active_face->foreground;
+              gc_values.background = hollow_active_region_beg_face->foreground;
+            }
+            else if (region_active_p
+                     && active_p
+                     && cursor_glyph->charpos == region_end)
+              {
+                enum face_id hollow_active_region_end_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                struct face *hollow_active_region_end_face = FACE_FROM_ID (f, hollow_active_region_end_face_id);
+                enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                gc_values.foreground = hollow_active_face->foreground;
+                gc_values.background = hollow_active_region_end_face->background;
+              }
+              else if (region_active_p
+                       && active_p
+                       && cursor_glyph->charpos > region_beg
+                       && cursor_glyph->charpos < region_end)
+                {
+                  enum face_id hollow_active_region_between_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+                  struct face *hollow_active_region_between_face = FACE_FROM_ID (f, hollow_active_region_between_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  gc_values.foreground = hollow_active_face->foreground;
+                  gc_values.background = hollow_active_region_between_face->foreground;
+                }
+                else if (active_p)
+                  {
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                    struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                    gc_values.foreground = hollow_active_face->foreground;
+                    gc_values.background = hollow_active_face->background;
+                  }
+                  else if (!active_p)
+                    {
+                      enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-pre-zv-face"), true);
+                      struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                      gc_values.foreground = hollow_inactive_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 `mc_w32_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'.  */
+          bool cursor_gc_p = true;
+          mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                                glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+          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;
+          mc_w32_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else if (cursor_glyph->type == IMAGE_GLYPH && lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+          {
+            /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+            f->output_data.w32->cursor_pixel = color_pixel;
+            mc_w32_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+            f->output_data.w32->cursor_pixel = original_cursor_pixel;
+          }
+          else
+            {
+              /* Temporarily hijack `f->output_data.w32->cursor_gc' by borrowing the
+              functionality of `x_make_gc' in w32fns.c.  */
+              if (region_active_p
+                  && active_p
+                  && cursor_glyph->charpos == region_beg)
+                {
+                  enum face_id hollow_active_region_beg_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                  struct face *hollow_active_region_beg_face = FACE_FROM_ID (f, hollow_active_region_beg_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  gc_values.foreground = hollow_active_face->foreground;
+                  gc_values.background = hollow_active_region_beg_face->foreground;
+                }
+                else if (region_active_p
+                         && active_p
+                         && cursor_glyph->charpos == region_end)
+                  {
+                    enum face_id hollow_active_region_end_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                    struct face *hollow_active_region_end_face = FACE_FROM_ID (f, hollow_active_region_end_face_id);
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                    struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                    gc_values.foreground = hollow_active_face->foreground;
+                    gc_values.background = hollow_active_region_end_face->background;
+                  }
+                  else if (region_active_p
+                           && active_p
+                           && cursor_glyph->charpos > region_beg
+                           && cursor_glyph->charpos < region_end)
+                    {
+                      enum face_id hollow_active_region_between_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+                      struct face *hollow_active_region_between_face = FACE_FROM_ID (f, hollow_active_region_between_face_id);
+                      enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                      struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                      gc_values.foreground = hollow_active_face->foreground;
+                      gc_values.background = hollow_active_region_between_face->foreground;
+                    }
+                    else if (active_p)
+                      {
+                        enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true);
+                        struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                        gc_values.foreground = hollow_active_face->foreground;
+                        gc_values.background = hollow_active_face->background;
+                      }
+                      else if (!active_p)
+                        {
+                          enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-pre-zv-face"), true);
+                          struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                          gc_values.foreground = hollow_inactive_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 `mc_w32_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'.  */
+              bool cursor_gc_p = true;
+              mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos,
+                                    lsl, glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+              f->output_data.w32->cursor_gc = original_cursor_gc;
+              unblock_input ();
+              mc_w32_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+            }
+      break;
+    }
+    case MC_HOLLOW_BOX:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          mc_w32_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          mc_w32_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+      break;
+    }
+    case MC_FILLED_BOX:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 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 `mc_w32_set_cursor_gc' to use `s->f->output_data.w32->cursor_gc'.  */
+          bool cursor_gc_p = true;
+          mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                                glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+          f->output_data.w32->cursor_gc = original_cursor_gc;
+          unblock_input ();
+        }
+        else
+          {
+            bool cursor_gc_p = false;
+            mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos,
+                                  lsl, glyph_flavor, cursor_type, wd, active_p,
+                                  cursor_gc_p);
+          }
+      break;
+    }
+    case MC_BAR:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          bool cursor_gc_invisible_okay_p = true;
+          mc_w32_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                  h, cursor_width, MC_BAR, cursor_gc_invisible_okay_p);
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          {
+            bool cursor_gc_invisible_okay_p = false;
+            mc_w32_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                    h, cursor_width, MC_BAR, cursor_gc_invisible_okay_p);
+          }
+      break;
+    }
+    case MC_HBAR:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.w32->cursor_pixel'.  */
+          f->output_data.w32->cursor_pixel = color_pixel;
+          bool cursor_gc_invisible_okay_p = true;
+          mc_w32_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                  h, cursor_width, MC_HBAR, cursor_gc_invisible_okay_p);
+          f->output_data.w32->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          {
+            bool cursor_gc_invisible_okay_p = false;
+            mc_w32_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                    h, cursor_width, MC_HBAR, cursor_gc_invisible_okay_p);
+          }
+      break;
+    }
+    default:
+      emacs_abort ();
+  }
+    }
+}
+
+/* Draw glyph string S.  */
+static void
+mc_w32_draw_glyph_string (struct glyph_string *s, struct glyph_matrix *matrix, struct glyph_row *row,
+                          struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+                          enum mc_cursor_type cursor_type, int cursor_width,
+                          bool active_p, bool cursor_gc_p)
+{
+  bool relief_drawn_p = 0;
+  /* If S draws into the background of its successor, draw the
+     background of the successor first so that S can draw into it.
+     This makes S->next use XDrawString instead of XDrawImageString.  */
+  if (s->next && s->right_overhang && !s->for_overlaps)
+    {
+      int width;
+      struct glyph_string *next;
+      for (width = 0, next = s->next;
+           next && width < s->right_overhang;
+           width += next->width, next = next->next)
+        if (next->first_glyph->type != IMAGE_GLYPH)
+          {
+            mc_w32_set_glyph_string_gc (next, cursor_gc_p);
+            x_set_glyph_string_clipping (next);
+            if (next->first_glyph->type == STRETCH_GLYPH)
+              mc_w32_draw_stretch_glyph_string (next);
+            else
+              x_draw_glyph_string_background (next, true);
+            next->num_clips = 0;
+          }
+    }
+  /* Set up S->gc, set clipping and draw S.  */
+  mc_w32_set_glyph_string_gc (s, cursor_gc_p);
+  /* Draw relief (if any) in advance for char/composition so that the
+     glyph string can be drawn over it.  */
+  if (!s->for_overlaps
+      && s->face->box != FACE_NO_BOX
+      && (s->first_glyph->type == CHAR_GLYPH
+          || s->first_glyph->type == COMPOSITE_GLYPH))
+    {
+      x_set_glyph_string_clipping (s);
+      x_draw_glyph_string_background (s, true);
+      x_draw_glyph_string_box (s);
+      x_set_glyph_string_clipping (s);
+      relief_drawn_p = 1;
+    }
+  else if (!s->clip_head /* draw_glyphs didn't specify a clip mask.  */
+           && !s->clip_tail
+           && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+               || (s->next && s->next->hl != s->hl && s->right_overhang)))
+    /* We must clip just this glyph.  left_overhang part has already
+       drawn when s->prev was drawn, and right_overhang part will be
+       drawn later when s->next is drawn. */
+    x_set_glyph_string_clipping_exactly (s, s);
+  else
+    x_set_glyph_string_clipping (s);
+  switch (s->first_glyph->type)
+    {
+    case IMAGE_GLYPH:
+      x_draw_image_glyph_string (s);
+      break;
+    case STRETCH_GLYPH:
+      mc_w32_draw_stretch_glyph_string (s);
+      break;
+    case CHAR_GLYPH:
+      if (s->for_overlaps)
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, false);
+      x_draw_glyph_string_foreground (s);
+      break;
+    case COMPOSITE_GLYPH:
+      if (s->for_overlaps || (s->cmp_from > 0
+          && ! s->first_glyph->u.cmp.automatic))
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, true);
+      x_draw_composite_glyph_string_foreground (s);
+      break;
+    case GLYPHLESS_GLYPH:
+      if (s->for_overlaps)
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, false);
+      x_draw_glyphless_glyph_string_foreground (s);
+      break;
+    default:
+      emacs_abort ();
+    }
+  if (!s->for_overlaps)
+    {
+      /* Draw underline.  */
+      if (s->face->underline_p)
+        {
+          if (s->face->underline_type == FACE_UNDER_WAVE)
+            {
+              COLORREF color;
+              if (s->face->underline_defaulted_p)
+                color = s->gc->foreground;
+              else
+                color = s->face->underline_color;
+              w32_draw_underwave (s, color);
+            }
+          else if (s->face->underline_type == FACE_UNDER_LINE)
+            {
+              unsigned long thickness, position;
+              int y;
+              if (s->prev && s->prev->face->underline_p
+                  && s->prev->face->underline_type == FACE_UNDER_LINE)
+                {
+                  /* We use the same underline style as the previous one.  */
+                  thickness = s->prev->underline_thickness;
+                  position = s->prev->underline_position;
+                }
+              else
+                {
+                  /* Get the underline thickness.  Default is 1 pixel.  */
+                  if (s->font && s->font->underline_thickness > 0)
+                    thickness = s->font->underline_thickness;
+                  else
+                    thickness = 1;
+                  if (x_underline_at_descent_line)
+                    position = (s->height - thickness) - (s->ybase - s->y);
+                  else
+                    {
+                      /* Get the underline position.  This is the recommended
+                         vertical offset in pixels from the baseline to the top of
+                         the underline.  This is a signed value according to the
+                         specs, and its default is
+                         ROUND ((maximum_descent) / 2), with
+                         ROUND (x) = floor (x + 0.5)  */
+                      if (x_use_underline_position_properties
+                          && s->font && s->font->underline_position >= 0)
+                        position = s->font->underline_position;
+                      else if (s->font)
+                        position = (s->font->descent + 1) / 2;
+                    }
+                  position = max (position, underline_minimum_offset);
+                }
+              /* Check the sanity of thickness and position.  We should
+                 avoid drawing underline out of the current line area.  */
+              if (s->y + s->height <= s->ybase + position)
+                position = (s->height - 1) - (s->ybase - s->y);
+              if (s->y + s->height < s->ybase + position + thickness)
+                thickness = (s->y + s->height) - (s->ybase + position);
+              s->underline_thickness = thickness;
+              s->underline_position =position;
+              y = s->ybase + position;
+              if (s->face->underline_defaulted_p)
+                w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+                               y, s->width, 1);
+              else
+                w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
+                               y, s->width, 1);
+            }
+        }
+      /* Draw overline.  */
+      if (s->face->overline_p)
+        {
+          unsigned long dy = 0, h = 1;
+          if (s->face->overline_color_defaulted_p)
+            w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+                           s->y + dy, s->width, h);
+            else
+              w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
+                             s->y + dy, s->width, h);
+        }
+      /* Draw strike-through.  */
+      if (s->face->strike_through_p
+          && !FONT_TEXTMETRIC (s->font).tmStruckOut)
+        {
+          unsigned long h = 1;
+          unsigned long dy = (s->height - h) / 2;
+          if (s->face->strike_through_color_defaulted_p)
+            w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
+                           s->width, h);
+          else
+            w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
+                           s->y + dy, s->width, h);
+        }
+      /* Draw relief if not yet drawn.  */
+      if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+        x_draw_glyph_string_box (s);
+      if (s->prev)
+        {
+          struct glyph_string *prev;
+          for (prev = s->prev; prev; prev = prev->prev)
+            if (prev->hl != s->hl
+                && prev->x + prev->width + prev->right_overhang > s->x)
+              {
+                /* As prev was drawn while clipped to its own area, we
+                   must draw the right_overhang part using s->hl now.  */
+                enum draw_glyphs_face save = prev->hl;
+                prev->hl = s->hl;
+                mc_w32_set_glyph_string_gc (prev, cursor_gc_p);
+                x_set_glyph_string_clipping_exactly (s, prev);
+                if (prev->first_glyph->type == CHAR_GLYPH)
+                  x_draw_glyph_string_foreground (prev);
+                else
+                  x_draw_composite_glyph_string_foreground (prev);
+                w32_set_clip_rectangle (prev->hdc, NULL);
+                prev->hl = save;
+                prev->num_clips = 0;
+              }
+        }
+      if (s->next)
+        {
+          struct glyph_string *next;
+          for (next = s->next; next; next = next->next)
+            if (next->hl != s->hl
+                && next->x - next->left_overhang < s->x + s->width)
+              {
+                /* As next will be drawn while clipped to its own area,
+                   we must draw the left_overhang part using s->hl now.  */
+                enum draw_glyphs_face save = next->hl;
+                next->hl = s->hl;
+                mc_w32_set_glyph_string_gc (next, cursor_gc_p);
+                x_set_glyph_string_clipping_exactly (s, next);
+                if (next->first_glyph->type == CHAR_GLYPH)
+                  x_draw_glyph_string_foreground (next);
+                else
+                  x_draw_composite_glyph_string_foreground (next);
+                w32_set_clip_rectangle (next->hdc, NULL);
+                next->hl = save;
+                next->num_clips = 0;
+                next->clip_head = s->next;
+              }
+        }
+    }
+  /* Reset clipping.  */
+  w32_set_clip_rectangle (s->hdc, NULL);
+  s->num_clips = 0;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Fringe bitmaps.  */
 
 static int max_fringe_bmp = 0;
@@ -545,6 +1417,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 +1635,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;
+
+/* *************************************************************************** */
+
+
 }
 
 
@@ -4041,13 +4932,74 @@ w32_set_vertical_scroll_bar (struct window *w,
 	      release_frame_dc (f, hdc);
 	      x_clear_under_internal_border (f);
 	    }
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+/* REPAINTING WHEN REMOVING SCROLL BAR:
+
+- Sequence of Events:
+
+  . `redisplay_internal' calls the `condemn_scroll_bars_hook', which marks all
+    scroll bars as candidates for deletion.
+
+  . Then `redisplay_internal' calls `redisplay_windows', which walks the
+    window-tree and examines each window, whereby each window that is still alive
+    in the window-tree "redeems" its scroll bars by marking them not to be
+    deleted.
+
+  . Then `redisplay_internal' calls `judge_scroll_bars_hook', which removes all
+    the scroll bars that were not "redeemed".
+
+  . And only after that `redisplay_internal' calls `update_frame', which calls
+    `update_window' for each live window, and that ends up calling `draw_glyphs'
+    to deliver the updated contents to the glass.
+
+- Observations by @lawlist:
+
+  . Although the call to remove/add scroll bars happens earlier in time, it is
+    not actually processed by Emacs until the tail end of `read_char', at
+    approximately when the call to `read_decoded_event_from_main_queue' occurs.
+
+  . Although a scroll bar may no longer be visible because it was overwritten
+    during `update_window', Emacs tries to remove the outdated scroll bar
+    anyway and that is what erases the fake cursors along the rectangle of the
+    vertical scroll bar.
+
+  . At about the exact same time that the scroll bar in the center of the screen
+    gets erased, the right scroll bar on the far right of the window is added.
+
+- The external function `MoveWindow' (by Microsoft) updates both the old and new
+  rectangles/windows if the boolean argument for `bRepaint` is TRUE.
+
+- The external function `DestroyWindow' (by Microsoft) updates/repaints the
+  rectangle/window that is removed.  [In experimenting with `LockWindowUpdate'
+  (by Microsoft), @lawlist was unable to prevent the update/repaint.]
+
+- The external function `SetWindowPos' (by Microsoft) updates/repaints the
+  rectangle/window that is removed.  @lawlist has not yet experimented with
+  altering the last argument uFlags to see if it is possible to prevent update /
+  repaint.
+
+When a user enlarges the width of a main window, `update_window' redraws the
+screen lines and the old scroll bar window is erased in the process by a
+combination of `draw_glyphs' and `x_clear_end_of_line'.  In that situation, the
+old `bar->left` will be less-than the new `left` scroll bar coordinate.  In order
+to preserve the fake cursors that were laid during `update_window' when
+(left > bar->left), we want to suppress repainting the old scroll.  When a user
+shrinks the width of a window, we want to repaint so that the new scroll bar
+window is updated. */
+
           /* Make sure scroll bar is "visible" before moving, to ensure the
              area of the parent window now exposed will be refreshed.  */
-          my_show_window (f, hwnd, SW_HIDE);
-/**           MoveWindow (hwnd, left, top, width, max (height, 1), TRUE); **/
-	  /* Try to not draw over child frames.  */
-	  SetWindowPos (hwnd, HWND_BOTTOM, left, top, width, max (height, 1),
-                        SWP_FRAMECHANGED);
+          if (left <= bar->left)
+            my_show_window (f, hwnd, SW_HIDE);
+          MoveWindow (hwnd, left, top, width, max (height, 1), left <= bar->left);
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
 
 	  si.cbSize = sizeof (si);
 	  si.fMask = SIF_RANGE;
@@ -4316,6 +5268,21 @@ w32_judge_scroll_bars (struct frame *f)
     {
       struct scroll_bar *b = XSCROLL_BAR (bar);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      /* `DestroyWindow' within `x_scroll_bar_remove' repaints the rectangle.
+      Therefore, we first send a message to inhibit repainting. */
+      if (!WINDOW_LIVE_P (b->window))
+        {
+          HWND hwnd = SCROLL_BAR_W32_WINDOW (b);
+          SendMessage (hwnd, WM_SETREDRAW, false, 0);
+        }
+
+/* *************************************************************************** */
+
+
       x_scroll_bar_remove (b);
 
       next = b->next;
@@ -7091,6 +8058,20 @@ extern frame_parm_handler w32_frame_parm_handlers[];
 
 static struct redisplay_interface w32_redisplay_interface =
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* `redisplay_interface' in `w32term.c` must be in the exact same order as the
+`redisplay_interface' in `dispextern.h`! */
+
+  mc_w32_draw_window_cursor,
+  mc_w32_draw_glyph_string,
+
+/* *************************************************************************** */
+
+
   w32_frame_parm_handlers,
   x_produce_glyphs,
   x_write_glyphs,
diff --git a/src/window.h b/src/window.h
index fdef407..2b0b9b4 100644
--- a/src/window.h
+++ b/src/window.h
@@ -324,6 +324,147 @@ struct window
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+/* Suffixes for the `mc` window pointer prefix. */
+struct multiple_cursors
+{
+  /* The recorded pixel width of the last line number drawn during redisplay */
+  int lnum_pixel_width;
+} mc;
+
+struct mc_matrix
+{
+  ptrdiff_t vpos_allocated;
+  ptrdiff_t vpos_used;
+  ptrdiff_t cursors_used[4];
+  enum mc_cache_type
+  {
+    MC_CACHE,
+    CH_CACHE,
+    FC_CACHE,
+    NO_CACHE
+  } cache_type;
+  struct mc_vpos
+  {
+    ptrdiff_t cache_allocated[4];
+    ptrdiff_t cache_used[4];
+    struct mc_contents
+    {
+      bool_bf same_p : 1;
+      struct glyph glyph;
+      int x;
+      int fx;
+      int y;
+      int fy;
+      int hpos;
+      int vpos;
+      int wd;
+      int h;
+      enum mc_cursor_type
+      {
+        /* NOTE:  The fringe bitmap framework relies upon MC_NO_FRINGE_BITMAP
+        having a value of zero (0). */
+        MC_NO_FRINGE_BITMAP,
+        MC_NO_CURSOR,
+        MC_RIGHT_FRINGE_BITMAP,
+        MC_LEFT_FRINGE_BITMAP,
+        MC_FRAMED_BOX,
+        MC_FILLED_BOX,
+        MC_HOLLOW_BOX,
+        MC_BAR,
+        MC_HBAR
+      } cursor_type;
+      int cursor_width;
+      struct mc_RGB
+      {
+        double red;
+        double green;
+        double blue;
+      } fg, bg;
+      bool_bf active_p : 1;
+      enum mc_flavor
+      {
+        NO_FLAVOR,
+        MC_GLYPH,
+        MC_GLYPHLESS,
+        MC_OVERLAY_ARROW_BITMAP,
+        MC_PILCROW,
+        MC_HOLLOW_RECTANGLE_RIGHT_ARROW,
+        MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW,
+        MC_HOLLOW_RECTANGLE,
+        MC_VERTICAL_BAR_RIGHT_ARROW,
+        MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW,
+        MC_VERTICAL_BAR,
+        MC_REVERSED_VERTICAL_BAR,
+        MC_VERTICAL_BAR_BACKSLASH
+      } glyph_flavor;
+      bool_bf enabled_p : 1;
+    } *cache[4];
+  } *vpos;
+  /* Used elsewhere. */
+  struct mc_essentials
+  {
+    enum mc_row_position
+    {
+      PRE_ZV,
+      AT_ZV,
+      POST_ZV
+    } row_position;
+    bool_bf active_p : 1;
+    struct mc_RGB ch_fg[3], fc_fg[3], sp_fg;
+    int fc_x;
+    int zv;
+    int zv_byte;
+  } essentials;
+  /* Used elsewhere. */
+  enum mc_engine_type
+  {
+    MULTIPLE_CURSORS,
+    HORIZONTAL_RULER,
+    VERTICAL_RULER,
+    FILL_COLUMN,
+    CURSOR_INDICATOR
+  } action_type;
+  /* Used elsewhere. */
+  enum mc_pre_scroll_clean_type
+  {
+    TRY_WINDOW_REUSING_CURRENT_MATRIX_DOWN,
+    TRY_WINDOW_REUSING_CURRENT_MATRIX_UP,
+    TRY_WINDOW_ID
+  } mc_pre_scroll_clean_type__from_where;
+  /* Used elsewhere. */
+  enum mc_draw_row_type
+  {
+    NOWHERE,
+    SCRIBE_ONE,
+    SCRIBE_TWO,
+    SCRIBE_THREE,
+    SKIPPED,
+    POST_CHANGED,
+    UNCHANGED,
+    SET_CURSOR_ONE,
+    SET_CURSOR_TWO
+  } mc_draw_row_type__from_where;
+  /* Used elsewhere. */
+  enum mc_redraw_row_type
+  {
+    UPDATE_WINDOW__REDRAW_OVERLAPPED_ROWS,
+    X_INSERT_GLYPHS,
+    X_FIX_OVERLAPPING_AREA,
+    DRAW_ROW_WITH_MOUSE_FACE,
+    EXPOSE_AREA_ONE,
+    EXPOSE_AREA_TWO,
+    EXPOSE_LINE
+  } mc_redraw_row_type__from_where;
+} mc_matrix;
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
     /* Cursor type of last cursor drawn on the window.  */
     enum text_cursor_kinds phys_cursor_type;
 
diff --git a/src/xdisp.c b/src/xdisp.c
index a88fc69..de64f25 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -921,6 +921,4647 @@ 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)
+
+
+VERSION:
+
+- 021.004 [06/29/2019]
+- 021.003 [06/23/2019]
+- 021.002 [06/15/2019]
+- 021.001 [06/08/2019]
+- 021.000 [06/01/2019]
+- 020.000 [05/27/2019]
+- 019.000 [04/20/2019]
+- 018.000 [04/08/2019]
+- 017.000 [12/13/2018]
+- 016.000 [11/20/2018]
+- 015.000 [11/10/2018]
+- 014.000 [08/28/2018]
+
+
+CHANGELOG:
+
+- Fake cursors can now be suppressed in the inactive windows by setting to `nil'
+  the buffer-local variables `mc-inactive-windows', `fc-inactive-windows', and/or
+  `ch-inactive-windows'.  The left fringe bitmap indicator that coincides with
+  the line containing POINT (if `ch-horizontal-ruler' is non-nil) is drawn in the
+  inactive windows regardless of the boolean value of `ch-inactive-windows' --
+  this is an intended feature.  The real fake cursor coinciding with the line
+  containing POINT for inactive windows is drawn in the inactive windows -- this
+  is an intended feature.  [Support for _suppression_ of fake cursors in the
+  inactive windows had previously been disabled for an appreciable period of time
+  because work needed to be done to ensure fake cursors are drawn correctly when
+  `mc/fc/ch-inactive-windows' is non-nil; e.g., different colors for fake cursors
+  in the inactive-windows.]
+
+- Miscellaneous tidying-up of some code.
+
+
+SCREENSHOTS (X11, W32, NS):
+
+https://www.lawlist.com/images/22873_17684_light_dark_backgrounds.png
+
+
+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 04/08/2019:
+
+git reset --hard a038df77de7b1aa2d73a6478493b8838b59e4982
+
+Step 3:  From within the new emacs folder created in Step 1, apply the patch:
+
+git apply /path/to/the/patch.diff
+
+Step 4:  ./autogen.sh
+
+Step 5:  ./configure ... [your custom options]
+
+Step 6:  make
+
+Step 7:  make install
+
+
+USAGE:
+
+- For a minimal working example of built-in fake cursors, type:  M-x mc-test
+
+  ;;; TURN ON FAKE CURSORS (buffer position, cursor-type, cursor color):
+
+  (setq mc-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])
+                  (7 "framed" "OrangeRed"))))
+
+  ;;; TURN OFF FAKE CURSORS:
+
+  (setq mc-conf nil)
+
+- To try out both the crosshairs feature and the visible fill column indicator
+  feature, type:  M-x +-mode
+
+- To try out just the visible fill column indicator feature, type:  M-x fc-mode
+
+- To try out built-in fake cursors with Magnar Sveen's multiple-cursors package,
+  that package must be installed.  If the multiple-cursors package is already
+  installed, then just (require 'crosshairs) and `crosshairs.el` will redefine a
+  few of the multiple-cursors functions and set up a few keyboard shortcuts.
+  If the multiple-cursors package by Magnar Sveen is not already installed, then
+  here 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)
+    (mc/built-in-cursors))
+
+
+TODO:
+
+- When an idle-timer fires and point is at the end of a horizontally scrolled
+  line in a narrow window, the temporary horizontal scroll is canceled.  Create
+  a minimal working example and file a bug report.
+
+- `ns_draw_window_cursor' calls `ns_clip_to_rect', which does _not_ take
+  `row->clip` into consideration when drawing cursors with `NSRectFill'.  When
+  it comes time to draw glyphs on top of the box/hollow family of cursors,
+  `row->clip` is taken into consideration by `get_glyph_string_clip'.  Fake
+  cursors can be drawn even though the glyphs cannot, resulting in hollow/box
+  family of cursors without text.  The issue can be reproduced with M-x mc-test.
+  [A temporary workaround is to disable `row->clip` while drawing the glyphs.]
+  https://lists.gnu.org/archive/html/emacs-devel/2019-04/msg00009.html
+
+- Deal with left/right overwritten glyphs in the w32 and X ports of Emacs.
+
+- There is a bug affecting the recorded `w->mc.lnum_pixel_width` that is
+  observable when not running under gdb, but disappears when running under gdb.
+  While viewing a folded org-mode buffer, the non-gdb instance had a visible
+  line number pixel-width of 44, but Emacs treated it as fluctuating between
+  44 and 55 as the cursor was moved to the end of line.  In the gdb instance,
+  the visible line number pixel width was 55 with no fluctuation under the same
+  conditions as the non-gdb instance.  This appears to be a different bug than
+  bug#32177 (current line number shifts one column to the left) because the line
+  number of the current line does not shift left, and changing the bidi settings
+  did not correct the issue.
+
+- The current test for `auto_hscroll_mode_p' only looks for `current_line` and
+  all five related tests are based upon that assumption, which may not be true.
+
+- 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.
+
+- Implement functionality similar to the Lisp multiple-cursors by Magnar Sveen.
+
+- 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.
+
+- Is there any additional meaningful optimization that can be added to the
+  three calls of `mc_pre_scroll_clean'?
+
+- There is a bug affecting an older version of Emacs for the NS port that causes
+  partial line flickering when the same characters are grouped together (;;;;;;)
+  and MC_GLYPHLESS cursors are above or below -- having the same background color
+  as the frame; e.g., black on black (used to erase a glyphless cursor).  The
+  partial flickering is only noticeable with rapid fire; e.g., holding down the
+  right/left arrow key.  When changing the color of the glyphless cursor, the
+  issue is not present.  [@lawlist has verified that the X and HPOS coordinates
+  are accurate.]
+
+- NOTE:  As to `mc_scrolling_window', it would appear that there is no tangible
+  benefit to rotating the current/prospective cache of fake cursors to compare
+  the data before removing the fake cursors.  When scrolling the display, only
+  _some_ lines are copied to new locations.  Areas that are not overwritten may
+  have fake cursors and those may not necessarily be removed if desired/current
+  matrix glyphs are equal.  The test for `GLYPH_EQUAL_P' does not take into
+  consideration the existence of a fake cursor, and the glyph (with a fake
+  cursor) may not be updated as a result thereof.  As to lines that are not
+  copied, portions may be updated and fake cursors would be removed thereby.
+
+
+DEBUGGING:
+
+ns_focus + ns_clip_to_row => ns_clip_to_rect [BOOL ... struct frame *, NSRect *, int)
+
+ns_unfocus => ns_reset_clipping
+
+make_save_ptr => make_mint_ptr
+
+row->glyphs[TEXT_AREA][hpos].pixel_width
+
+w->current_matrix->rows[2]->glyphs[TEXT_AREA][hpos].pixel_width
+
+w->current_matrix->rows[2].enabled_p
+
+w->current_matrix->rows[2].used[TEXT_AREA]
+
+RANGED_INTEGERP => RANGED_FIXNUMP
+
+TYPE_RANGED_INTEGERP => TYPE_RANGED_FIXNUMP
+
+make_number => make_fixnum
+
+XINT => XFIXNUM
+
+XFASTINT => XFIXNAT
+
+struct frame *f = XFRAME (w->frame);
+  OR
+struct frame *f = XFRAME (WINDOW_FRAME (w));
+
+Lisp_Object string = Fprin1_to_string (i_store, Qnil);
+char *char_string = SSDATA (string);
+fprintf (stderr, "i_store:  %s\n", char_string);
+
+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 = ...
+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", "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)));
+
+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>
+
+bool mc_stderr_p = false;
+
+/* Function prototypes. */
+
+#ifdef HAVE_NTGUI
+#define MC_OPTIONAL_HDC(hdc)  HDC hdc,
+#define MC_DECLARE_HDC(hdc)   HDC hdc;
+#define MC_ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
+#define MC_RELEASE_HDC(hdc, f)  release_frame_dc ((f), (hdc))
+#endif
+
+#ifndef MC_OPTIONAL_HDC
+#define MC_OPTIONAL_HDC(hdc)
+#define MC_DECLARE_HDC(hdc)
+#define MC_ALLOCATE_HDC(hdc, f)
+#define MC_RELEASE_HDC(hdc, f)
+#endif
+
+static int left_overwritten (struct glyph_string *);
+static int right_overwritten (struct glyph_string *);
+static int left_overwriting (struct glyph_string *);
+static int right_overwriting (struct glyph_string *);
+static void append_glyph_string (struct glyph_string **, struct glyph_string **,
+                                 struct glyph_string *);
+static void prepend_glyph_string_lists (struct glyph_string **, struct glyph_string **,
+                                        struct glyph_string *, struct glyph_string *);
+static void append_glyph_string_lists (struct glyph_string **, struct glyph_string **,
+                                       struct glyph_string *, struct glyph_string *);
+static void init_glyph_string (struct glyph_string *, MC_OPTIONAL_HDC (hdc) XChar2b *,
+                               struct window *, struct glyph_row *,
+                               enum glyph_row_area, int, enum draw_glyphs_face);
+static void compute_overhangs_and_x (struct glyph_string *, int, bool);
+static struct glyph_string * glyph_string_containing_background_width (struct glyph_string *);
+static void set_glyph_string_background_width (struct glyph_string *, int, int);
+static int fill_glyph_string (struct glyph_string *, int, int, int, int);
+static int fill_gstring_glyph_string (struct glyph_string *, int, int, int, int);
+static int fill_composite_glyph_string (struct glyph_string *, struct face *, int);
+static int fill_stretch_glyph_string (struct glyph_string *, int, int);
+static void fill_image_glyph_string (struct glyph_string *);
+static int fill_glyphless_glyph_string (struct glyph_string *, int, int, int, int);
+
+#ifdef HAVE_NTGUI
+#define MC_INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
+  init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
+#else
+#define MC_INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
+  init_glyph_string (s, char2b, w, row, area, start, hl)
+#endif
+
+#define MC_BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X)   \
+     do									    \
+       {								    \
+	 s = alloca (sizeof *s);					    \
+	 MC_INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);		    \
+	 START = fill_stretch_glyph_string (s, START, END);                 \
+	 append_glyph_string (&HEAD, &TAIL, s);				    \
+         s->x = (X);							    \
+       }								    \
+     while (false)
+
+#define MC_BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     do									\
+       {								\
+	 s = alloca (sizeof *s);					\
+	 MC_INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);		\
+	 fill_image_glyph_string (s);					\
+	 append_glyph_string (&HEAD, &TAIL, s);				\
+	 ++START;							\
+         s->x = (X);							\
+       }								\
+     while (false)
+
+#ifndef HAVE_XWIDGETS
+# define MC_BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     eassume (false)
+#else
+# define MC_BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     do									\
+       {								\
+	 s = alloca (sizeof *s);					\
+	 MC_INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);		\
+	 fill_xwidget_glyph_string (s);					\
+	 append_glyph_string (&(HEAD), &(TAIL), s);			\
+	 ++(START);							\
+         s->x = (X);							\
+       }								\
+     while (false)
+#endif
+
+#define MC_BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)	   \
+     do									   \
+       {								   \
+	 int face_id;							   \
+	 XChar2b *char2b;						   \
+									   \
+	 face_id = (row)->glyphs[area][START].face_id;			   \
+									   \
+	 s = alloca (sizeof *s);					   \
+	 SAFE_NALLOCA (char2b, 1, (END) - (START));			   \
+	 MC_INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);	   \
+	 append_glyph_string (&HEAD, &TAIL, s);				   \
+	 s->x = (X);							   \
+	 START = fill_glyph_string (s, face_id, START, END, overlaps);	   \
+       }								   \
+     while (false)
+
+#define MC_BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+  do {									    \
+    int face_id = (row)->glyphs[area][START].face_id;			    \
+    struct face *base_face = FACE_FROM_ID (f, face_id);		    \
+    ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id;		    \
+    struct composition *cmp = composition_table[cmp_id];		    \
+    XChar2b *char2b;							    \
+    struct glyph_string *first_s = NULL;				    \
+    int n;								    \
+									    \
+    SAFE_NALLOCA (char2b, 1, cmp->glyph_len);				    \
+									    \
+    for (n = 0; n < cmp->glyph_len;)					    \
+      {									    \
+	s = alloca (sizeof *s);						    \
+	MC_INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);		    \
+	append_glyph_string (&(HEAD), &(TAIL), s);			    \
+	s->cmp = cmp;							    \
+	s->cmp_from = n;						    \
+	s->x = (X);							    \
+	if (n == 0)							    \
+	  first_s = s;							    \
+	n = fill_composite_glyph_string (s, base_face, overlaps);	    \
+      }									    \
+									    \
+    ++START;								    \
+    s = first_s;							    \
+  } while (false)
+
+#define MC_BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+  do {									  \
+    int face_id;							  \
+    XChar2b *char2b;							  \
+    Lisp_Object gstring;						  \
+									  \
+    face_id = (row)->glyphs[area][START].face_id;			  \
+    gstring = (composition_gstring_from_id				  \
+	       ((row)->glyphs[area][START].u.cmp.id));			  \
+    s = alloca (sizeof *s);						  \
+    SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring));		  \
+    MC_INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL);		  \
+    append_glyph_string (&(HEAD), &(TAIL), s);				  \
+    s->x = (X);								  \
+    START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
+  } while (false)
+
+#define MC_BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+  do									    \
+    {									    \
+      int face_id;							    \
+									    \
+      face_id = (row)->glyphs[area][START].face_id;			    \
+									    \
+      s = alloca (sizeof *s);						    \
+      MC_INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);		    \
+      append_glyph_string (&HEAD, &TAIL, s);				    \
+      s->x = (X);							    \
+      START = fill_glyphless_glyph_string (s, face_id, START, END,	    \
+					   overlaps);			    \
+    }									    \
+  while (false)
+
+#define MC_BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+  do									\
+    {									\
+      HEAD = TAIL = NULL;						\
+      while (START < END)						\
+	{								\
+	  struct glyph *first_glyph = (row)->glyphs[area] + START;	\
+	  switch (first_glyph->type)					\
+	    {								\
+	    case CHAR_GLYPH:						\
+	      MC_BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL,		\
+					HL, X, LAST_X);			\
+	      break;							\
+									\
+	    case COMPOSITE_GLYPH:					\
+	      if (first_glyph->u.cmp.automatic)				\
+		MC_BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL,	\
+					    HL, X, LAST_X);		\
+	      else							\
+		MC_BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL,	\
+					      HL, X, LAST_X);		\
+	      break;							\
+									\
+	    case STRETCH_GLYPH:						\
+	      MC_BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL,	\
+					  HL, X, LAST_X);		\
+	      break;							\
+									\
+	    case IMAGE_GLYPH:						\
+	      MC_BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,		\
+					HL, X, LAST_X);			\
+	      break;
+
+#define MC_BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+            case XWIDGET_GLYPH:                                         \
+              MC_BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL,       \
+                                          HL, X, LAST_X);               \
+              break;
+
+#define MC_BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+	    case GLYPHLESS_GLYPH:					\
+	      MC_BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL,	\
+					    HL, X, LAST_X);		\
+	      break;							\
+									\
+	    default:							\
+	      emacs_abort ();						\
+	    }								\
+									\
+	  if (s)							\
+	    {								\
+	      set_glyph_string_background_width (s, START, LAST_X);	\
+	      (X) += s->width;						\
+	    }								\
+	}								\
+    } while (false)
+
+#define MC_BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+    MC_BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+    MC_BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X)	\
+    MC_BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
+
+/* 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)
+
+Lisp_Object
+mc_vector (int length)
+{
+  struct Lisp_Vector *p = allocate_vector (length);
+  for (ptrdiff_t i = 0; i < length; i++)
+    p->contents[i] = Qnil;
+  return make_lisp_ptr (p, Lisp_Vectorlike);
+}
+
+Lisp_Object
+mc_listn (ptrdiff_t count, Lisp_Object arg, ...)
+{
+  eassume (0 < count);
+  Lisp_Object val = Fcons (arg, Qnil);
+  Lisp_Object tail = val;
+  va_list ap;
+  va_start (ap, arg);
+  for (ptrdiff_t i = 1; i < count; i++)
+    {
+      Lisp_Object elem = Fcons (va_arg (ap, Lisp_Object), Qnil);
+      XSETCDR (tail, elem);
+      tail = elem;
+    }
+  va_end (ap);
+  return val;
+}
+
+Lisp_Object
+mc_memq (Lisp_Object elt, Lisp_Object list)
+{
+  while (1)
+    {
+      if (!CONSP (list) || EQ (XCAR (list), elt))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list) || EQ (XCAR (list), elt))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list) || EQ (XCAR (list), elt))
+        break;
+      list = XCDR (list);
+    }
+  return list;
+}
+
+Lisp_Object
+mc_nth (int num, Lisp_Object list)
+{
+  for (int i = 0; i < num && !NILP (list); i++)
+    list = XCDR (list);
+  if (CONSP (list))
+    return XCAR (list);
+    else
+      return Qnil;
+}
+
+Lisp_Object
+mc_assq (Lisp_Object key, Lisp_Object list)
+{
+  while (1)
+    {
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && EQ (XCAR (XCAR (list)), key)))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && EQ (XCAR (XCAR (list)), key)))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && EQ (XCAR (XCAR (list)), key)))
+        break;
+      list = XCDR (list);
+    }
+  if (CONSP (list))
+    return XCAR (list);
+    else
+      return Qnil;
+}
+
+Lisp_Object
+mc_assoc (Lisp_Object key, Lisp_Object list)
+{
+  Lisp_Object car;
+  while (1)
+    {
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && (car = XCAR (XCAR (list)),
+                  EQ (car, key) || !NILP (Fequal (car, key)))))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && (car = XCAR (XCAR (list)),
+                  EQ (car, key) || !NILP (Fequal (car, key)))))
+        break;
+      list = XCDR (list);
+      if (!CONSP (list)
+          || (CONSP (XCAR (list))
+              && (car = XCAR (XCAR (list)),
+                  EQ (car, key) || !NILP (Fequal (car, key)))))
+        break;
+      list = XCDR (list);
+    }
+  if (CONSP (list))
+    return XCAR (list);
+    else
+      return Qnil;
+}
+
+Lisp_Object
+mc_plist_get (Lisp_Object plist, Lisp_Object prop)
+{
+  Lisp_Object tail, halftail;
+  /* halftail is used to detect circular lists.  */
+  tail = halftail = plist;
+  while (CONSP (tail) && CONSP (XCDR (tail)))
+    {
+      if (EQ (prop, XCAR (tail)))
+        return XCAR (XCDR (tail));
+      tail = XCDR (XCDR (tail));
+      halftail = XCDR (halftail);
+      if (EQ (tail, halftail))
+        break;
+    }
+  return Qnil;
+}
+
+/* REGION BEGIN:  mc_region_limit (1)
+   REGION END:  mc_region_limit (0) */
+ptrdiff_t
+mc_region_limit (bool begin_p)
+{
+  if (!NILP (Vtransient_mark_mode)
+      && NILP (Vmark_even_if_inactive)
+      && NILP (BVAR (current_buffer, mark_active)))
+    xsignal0 (Qmark_inactive);
+  Lisp_Object marker = BVAR (current_buffer, mark);
+  int m = (XMARKER (marker)->buffer)
+          ? XMARKER (marker)->charpos
+          : -1;
+  return (m == -1)
+           ? -1
+         : (PT < m) == begin_p
+           ? PT
+         : clip_to_bounds (BEGV, m, ZV);
+}
+
+/* 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 = mc_plist_get (plist, QCwidth), RANGED_FIXNUMP (0, prop, INT_MAX))
+          || (prop = mc_plist_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 = mc_plist_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 (mc_plist_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);
+  struct buffer *old_buffer = NULL;
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  bool barf_crash = (BUF_BEG (b) <= pt && pt <= BUF_Z (b)) ? false : true;
+  if (barf_crash)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      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)
+    {
+      if (old_buffer)
+        set_buffer_internal (old_buffer);
+      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);
+      {
+        if (old_buffer)
+          set_buffer_internal (old_buffer);
+        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;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+  return col;
+}
+
+DEFUN ("mc-current-column", Fmc_current_column, Smc_current_column, 2, 2, 0,
+       doc: /* Return the horizontal position of point.  Beginning of line is column 0.
+This is calculated by adding together the widths of all the displayed
+representations of the character between the start of the previous line
+and point (e.g., control characters will have a width of 2 or 4, tabs
+will have a variable width).
+Ignores finite width of frame, which means that this function may return
+values greater than (frame-width).
+Whether the line is visible (if `selective-display' is t) has no effect;
+however, ^M is treated as end of line when `selective-display' is t.
+Text that has an invisible property is considered as having width 0, unless
+`buffer-invisibility-spec' specifies that it is replaced by an ellipsis.  */)
+  (Lisp_Object window, Lisp_Object pt)
+{
+  struct window *w = decode_live_window (window);
+  Lisp_Object temp;
+  XSETFASTINT (temp, mc_current_column (w, XFIXNUM (pt)));
+  return temp;
+}
+
+/* USAGE:  fprintf (stderr, "FRAME (%s)", mc_frame (f)); */
+char *
+mc_frame (struct frame *f)
+{
+  Lisp_Object frame;
+  XSETFRAME (frame, f);
+  return SSDATA (Fprin1_to_string (frame, Qnil));
+}
+
+/* USAGE:  fprintf (stderr, "WINDOW (%s)", mc_window (w)); */
+char *
+mc_window (struct window *w)
+{
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  return SSDATA (Fprin1_to_string (window, Qnil));
+}
+
+/* USAGE:  fprintf (stderr, "CHARACTER (%s)", mc_char_to_string (glyph->u.ch)); */
+char *
+mc_char_to_string (int arg)
+{
+  Lisp_Object character = (0 <= arg && arg <= MAX_CHAR)
+                           ? Fchar_to_string (make_fixnum (arg))
+                           : Qnil;
+  char * result = (!NILP (character)
+                   && arg == 9)
+                    ? "\\t"
+                  : (!NILP (character)
+                     && arg == 10)
+                    ? "\\n"
+                  : (!NILP (character)
+                     && arg == 32)
+                    ? "\\s"
+                  : (!NILP (character)
+                     && arg != 9
+                     && arg != 10
+                     && arg != 32)
+                    ? SSDATA (character)
+                  : "\\?";
+  return result;
+}
+
+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, "no"))
+    return MC_NO_CURSOR;
+  if (!strcmp (str, "mc-left-fringe-bitmap"))
+    return MC_LEFT_FRINGE_BITMAP;
+  if (!strcmp (str, "mc-right-fringe-bitmap"))
+    return MC_RIGHT_FRINGE_BITMAP;
+  if (!strcmp (str, "box"))
+    return MC_FILLED_BOX;
+  if (!strcmp (str, "framed"))
+    return MC_FRAMED_BOX;
+  if (!strcmp (str, "hollow"))
+    return MC_HOLLOW_BOX;
+  if (!strcmp (str, "bar"))
+    return MC_BAR;
+  if (!strcmp (str, "hbar"))
+    return MC_HBAR;
+  return -1;
+}
+
+/* USAGE:  fprintf (stderr, "CURSOR TYPE (%s)", mc_cursor_type_to_string (arg)); */
+char *
+mc_cursor_type_to_string (enum mc_cursor_type cursor_type)
+{
+  switch (cursor_type)
+    {
+      case MC_FILLED_BOX: return "MC_FILLED_BOX";
+      case MC_FRAMED_BOX: return "MC_FRAMED_BOX";
+      case MC_HOLLOW_BOX: return "MC_HOLLOW_BOX";
+      case MC_BAR: return "MC_BAR";
+      case MC_HBAR: return "MC_HBAR";
+      case MC_LEFT_FRINGE_BITMAP: return "MC_LEFT_FRINGE_BITMAP";
+      case MC_RIGHT_FRINGE_BITMAP: return "MC_RIGHT_FRINGE_BITMAP";
+      case MC_NO_FRINGE_BITMAP: return "MC_NO_FRINGE_BITMAP";
+      case MC_NO_CURSOR:
+      default:
+      return "MC_NO_CURSOR";
+    }
+}
+
+/* USAGE:  fprintf (stderr, "GLYPH FLAVOR (%s)", mc_flavor_to_string (arg)); */
+char *
+mc_flavor_to_string (enum mc_flavor glyph_flavor)
+{
+  switch (glyph_flavor)
+    {
+      case NO_FLAVOR: return "NO_FLAVOR";
+      case MC_GLYPH: return "MC_GLYPH";
+      case MC_GLYPHLESS: return "MC_GLYPHLESS";
+      case MC_OVERLAY_ARROW_BITMAP: return "MC_OVERLAY_ARROW_BITMAP";
+      case MC_PILCROW: return "MC_PILCROW";
+      case MC_HOLLOW_RECTANGLE_RIGHT_ARROW: return "MC_HOLLOW_RECTANGLE_RIGHT_ARROW";
+      case MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW: return "MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW";
+      case MC_HOLLOW_RECTANGLE: return "MC_HOLLOW_RECTANGLE";
+      case MC_VERTICAL_BAR_RIGHT_ARROW: return "MC_VERTICAL_BAR_RIGHT_ARROW";
+      case MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW: return "MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW";
+      case MC_VERTICAL_BAR: return "MC_VERTICAL_BAR";
+      case MC_REVERSED_VERTICAL_BAR: return "MC_REVERSED_VERTICAL_BAR";
+      case MC_VERTICAL_BAR_BACKSLASH: return "MC_VERTICAL_BAR_BACKSLASH";
+      default:
+      return "UNKNOWN";
+    }
+}
+
+/* USAGE:  fprintf (stderr, "CACHE-TYPE (%s)", mc_cache_type_to_string (arg)); */
+char *
+mc_cache_type_to_string (enum mc_cache_type cache_type)
+{
+  switch (cache_type)
+    {
+      case NO_CACHE: return "NO_CACHE";
+      case MC_CACHE: return "MC_CACHE";
+      case CH_CACHE: return "CH_CACHE";
+      case FC_CACHE: return "FC_CACHE";
+      default:
+      return "UNKNOWN";
+    }
+}
+
+/* USAGE:  fprintf (stderr, "ACTION-TYPE (%s)", mc_engine_type_to_string (arg)); */
+char *
+mc_engine_type_to_string (enum mc_engine_type action_type)
+{
+  switch (action_type)
+    {
+      case MULTIPLE_CURSORS: return "MULTIPLE_CURSORS";
+      case HORIZONTAL_RULER: return "HORIZONTAL_RULER";
+      case VERTICAL_RULER: return "VERTICAL_RULER";
+      case FILL_COLUMN: return "FILL_COLUMN";
+      case CURSOR_INDICATOR: return "CURSOR_INDICATOR";
+      default:
+      return "UNKNOWN";
+    }
+}
+
+/* USAGE:  fprintf (stderr, "FROM_WHERE (%s)", mc_draw_row_type_to_string (arg)); */
+char *
+mc_draw_row_type_to_string (enum mc_draw_row_type from_where)
+{
+  switch (from_where)
+    {
+      case NOWHERE: return "NOWHERE";
+      case SCRIBE_ONE: return "SCRIBE_ONE";
+      case SCRIBE_TWO: return "SCRIBE_TWO";
+      case SCRIBE_THREE: return "SCRIBE_THREE";
+      case SKIPPED: return "SKIPPED";
+      case POST_CHANGED: return "POST_CHANGED";
+      case UNCHANGED: return "UNCHANGED";
+      case SET_CURSOR_ONE: return "SET_CURSOR_ONE";
+      case SET_CURSOR_TWO: return "SET_CURSOR_TWO";
+      default:
+      return "UNKNOWN";
+    }
+}
+
+/* USAGE:  fprintf (stderr, "FROM_WHERE (%s)", mc_draw_row_type_to_string (arg)); */
+char *
+mc_redraw_row_type_to_string (enum mc_redraw_row_type from_where)
+{
+  switch (from_where)
+    {
+      case UPDATE_WINDOW__REDRAW_OVERLAPPED_ROWS: return "UPDATE_WINDOW__REDRAW_OVERLAPPED_ROWS";
+      case X_INSERT_GLYPHS: return "X_INSERT_GLYPHS";
+      case X_FIX_OVERLAPPING_AREA: return "X_FIX_OVERLAPPING_AREA";
+      case DRAW_ROW_WITH_MOUSE_FACE: return "DRAW_ROW_WITH_MOUSE_FACE";
+      case EXPOSE_AREA_ONE: return "EXPOSE_AREA_ONE";
+      case EXPOSE_AREA_TWO: return "EXPOSE_AREA_TWO";
+      case EXPOSE_LINE: return "EXPOSE_LINE";
+      default:
+      return "UNKNOWN";
+    }
+}
+
+void
+mc_cache_inspector (struct window *w, struct mc_matrix matrix)
+{
+  int vpos_allocated = w->mc_matrix.vpos_allocated;
+  int vpos_used = w->mc_matrix.vpos_used;
+  fprintf (stderr, "%s:  matrix.vpos_allocated (%d) | matrix.vpos_used (%d)\n",
+                   mc_window (w), vpos_allocated, vpos_used);
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    {
+      int cursors_used = w->mc_matrix.cursors_used[cache_type];
+      fprintf (stderr, "  matrix.cursors_used[%s] (%d)\n",
+                       mc_cache_type_to_string (cache_type), cursors_used);
+    }
+  for (int vnth = 0;
+       vnth < w->mc_matrix.vpos_used;
+       ++vnth)
+    {
+      for (enum mc_cache_type cache_type = MC_CACHE;
+           cache_type < NO_CACHE;
+           ++cache_type)
+        {
+          int cache_allocated = w->mc_matrix.vpos[vnth].cache_allocated[cache_type];
+          int cache_used = w->mc_matrix.vpos[vnth].cache_used[cache_type];
+          fprintf (stderr, "    vnth (%d) | cache_allocated[%s] (%d) | cache_used[%s] (%d)\n",
+                           vnth,
+                           mc_cache_type_to_string (cache_type),
+                           cache_allocated,
+                           mc_cache_type_to_string (cache_type),
+                           cache_used);
+        }
+    }
+}
+
+void
+mc_set_lsl_bg (struct window *w, enum face_id face_id, struct mc_RGB *lsl)
+{
+  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);
+  Lisp_Object color = (face != NULL)
+                      ? face->lface[LFACE_BACKGROUND_INDEX]
+                      : build_string ("OrangeRed");
+  mc_xw_color_values (w, color, lsl);
+}
+
+void
+mc_set_essentials (struct window *w, struct mc_essentials *essentials)
+{
+  if (!BUFFERP (w->contents))
+    return;
+  if (NILP (BVAR (XBUFFER (w->contents), mc_conf))
+      && NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && NILP (BVAR (XBUFFER (w->contents), fc_visible)))
+    return;
+  struct frame *f = XFRAME (w->frame);
+  essentials->active_p = (w == XWINDOW (f->selected_window)
+                          && f == FRAME_DISPLAY_INFO (f)->x_highlight_frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  ptrdiff_t opoint = (w == XWINDOW (selected_window))
+                     ? PT
+                     : XFIXNUM (Fmarker_position (w->pointm));
+  ptrdiff_t current_col = mc_current_column (w, opoint);
+  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 hscl_x = w->hscroll * frame_char_width;
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  essentials->zv = ZV;
+  essentials->zv_byte = ZV_BYTE;
+  essentials->fc_x = (fill_column_p
+                      && !NILP (Vdisplay_line_numbers))
+                       ? (fill_col * frame_char_width) + w->mc.lnum_pixel_width - hscl_x
+                     : (fill_column_p
+                        && NILP (Vdisplay_line_numbers))
+                       ? (fill_col * frame_char_width) - hscl_x
+                     : 0;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+  enum face_id fill_column_pre_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+     && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+      ? lookup_named_face (w, f, intern ("fc-inactive-pre-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-inactive-pre-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-pre-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-inactive-pre-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-pre-zv-face"), true)
+    : lookup_named_face (w, f, intern ("fc-pre-zv-face"), true);
+  struct face *fill_column_pre_zv_face = FACE_FROM_ID (f, fill_column_pre_zv_face_id);
+  Lisp_Object fill_column_pre_zv_color = fill_column_pre_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB fc_pre_zv_fg;
+  mc_xw_color_values (w, fill_column_pre_zv_color, &fc_pre_zv_fg);
+  essentials->fc_fg[PRE_ZV].red = fc_pre_zv_fg.red;
+  essentials->fc_fg[PRE_ZV].green = fc_pre_zv_fg.green;
+  essentials->fc_fg[PRE_ZV].blue = fc_pre_zv_fg.blue;
+  enum face_id fill_column_at_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+     && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+      ? lookup_named_face (w, f, intern ("fc-inactive-at-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-inactive-at-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-at-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-inactive-at-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-at-zv-face"), true)
+    : lookup_named_face (w, f, intern ("fc-at-zv-face"), true);
+  struct face *fill_column_at_zv_face = FACE_FROM_ID (f, fill_column_at_zv_face_id);
+  Lisp_Object fill_column_at_zv_color = fill_column_at_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB fc_at_zv_fg;
+  mc_xw_color_values (w, fill_column_at_zv_color, &fc_at_zv_fg);
+  essentials->fc_fg[AT_ZV].red = fc_at_zv_fg.red;
+  essentials->fc_fg[AT_ZV].green = fc_at_zv_fg.green;
+  essentials->fc_fg[AT_ZV].blue = fc_at_zv_fg.blue;
+  enum face_id fill_column_post_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+     && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+      ? lookup_named_face (w, f, intern ("fc-inactive-post-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-inactive-post-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-post-zv-face"), true)
+    : (!essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-inactive-post-zv-face"), true)
+    : (essentials->active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != essentials->fc_x)
+      ? lookup_named_face (w, f, intern ("fc-post-zv-face"), true)
+    : lookup_named_face (w, f, intern ("fc-post-zv-face"), true);
+  struct face *fill_column_post_zv_face = FACE_FROM_ID (f, fill_column_post_zv_face_id);
+  Lisp_Object fill_column_post_zv_color = fill_column_post_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB fc_post_zv_fg;
+  mc_xw_color_values (w, fill_column_post_zv_color, &fc_post_zv_fg);
+  essentials->fc_fg[POST_ZV].red = fc_post_zv_fg.red;
+  essentials->fc_fg[POST_ZV].green = fc_post_zv_fg.green;
+  essentials->fc_fg[POST_ZV].blue = fc_post_zv_fg.blue;
+  enum face_id even_pre_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-inactive-pre-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-pre-zv-face"), true);
+  struct face *even_pre_zv_face = FACE_FROM_ID (f, even_pre_zv_face_id);
+  Lisp_Object even_pre_zv_color = even_pre_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB even_pre_zv_fg;
+  mc_xw_color_values (w, even_pre_zv_color, &even_pre_zv_fg);
+  enum face_id even_at_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-inactive-at-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-at-zv-face"), true);
+  struct face *even_at_zv_face = FACE_FROM_ID (f, even_at_zv_face_id);
+  Lisp_Object even_at_zv_color = even_at_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB even_at_zv_fg;
+  mc_xw_color_values (w, even_at_zv_color, &even_at_zv_fg);
+  enum face_id even_post_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-inactive-post-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-post-zv-face"), true);
+  struct face *even_post_zv_face = FACE_FROM_ID (f, even_post_zv_face_id);
+  Lisp_Object even_post_zv_color = even_post_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB even_post_zv_fg;
+  mc_xw_color_values (w, even_post_zv_color, &even_post_zv_fg);
+  enum face_id odd_pre_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-inactive-pre-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-pre-zv-face"), true);
+  struct face *odd_pre_zv_face = FACE_FROM_ID (f, odd_pre_zv_face_id);
+  Lisp_Object odd_pre_zv_color = odd_pre_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB odd_pre_zv_fg;
+  mc_xw_color_values (w, odd_pre_zv_color, &odd_pre_zv_fg);
+  enum face_id odd_at_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-inactive-at-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-at-zv-face"), true);
+  struct face *odd_at_zv_face = FACE_FROM_ID (f, odd_at_zv_face_id);
+  Lisp_Object odd_at_zv_color = odd_at_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB odd_at_zv_fg;
+  mc_xw_color_values (w, odd_at_zv_color, &odd_at_zv_fg);
+  enum face_id odd_post_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-inactive-post-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-post-zv-face"), true);
+  struct face *odd_post_zv_face = FACE_FROM_ID (f, odd_post_zv_face_id);
+  Lisp_Object odd_post_zv_color = odd_post_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB odd_post_zv_fg;
+  mc_xw_color_values (w, odd_post_zv_color, &odd_post_zv_fg);
+  enum face_id post_fill_pre_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-post-fill-inactive-pre-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-post-fill-pre-zv-face"), true);
+  struct face *post_fill_pre_zv_face = FACE_FROM_ID (f, post_fill_pre_zv_face_id);
+  Lisp_Object post_fill_pre_zv_color = post_fill_pre_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB post_fill_pre_zv_fg;
+  mc_xw_color_values (w, post_fill_pre_zv_color, &post_fill_pre_zv_fg);
+  enum face_id post_fill_at_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-post-fill-inactive-at-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-post-fill-at-zv-face"), true);
+  struct face *post_fill_at_zv_face = FACE_FROM_ID (f, post_fill_at_zv_face_id);
+  Lisp_Object post_fill_at_zv_color = post_fill_at_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB post_fill_at_zv_fg;
+  mc_xw_color_values (w, post_fill_at_zv_color, &post_fill_at_zv_fg);
+  enum face_id post_fill_post_zv_face_id =
+    (!essentials->active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-post-fill-inactive-post-zv-face"), true)
+    : lookup_named_face (w, f, intern ("+-post-fill-post-zv-face"), true);
+  struct face *post_fill_post_zv_face = FACE_FROM_ID (f, post_fill_post_zv_face_id);
+  Lisp_Object post_fill_post_zv_color = post_fill_post_zv_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB post_fill_post_zv_fg;
+  mc_xw_color_values (w, post_fill_post_zv_color, &post_fill_post_zv_fg);
+  enum face_id special_char_face_id =
+    lookup_named_face (w, f, intern ("+-special-character-face"), true);
+  struct face *special_char_face = FACE_FROM_ID (f, special_char_face_id);
+  Lisp_Object special_char_fg_color = special_char_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB sp_foreground;
+  mc_xw_color_values (w, special_char_fg_color, &sp_foreground);
+  essentials->sp_fg.red = sp_foreground.red;
+  essentials->sp_fg.green = sp_foreground.green;
+  essentials->sp_fg.blue = sp_foreground.blue;
+  /* red */
+  if ((!fill_column_p
+       && current_col % 2 != 0)
+      || (fill_column_p
+          && current_col % 2 != 0
+          && current_col <= fill_col))
+    {
+      essentials->ch_fg[PRE_ZV].red = odd_pre_zv_fg.red;
+      essentials->ch_fg[PRE_ZV].green = odd_pre_zv_fg.green;
+      essentials->ch_fg[PRE_ZV].blue = odd_pre_zv_fg.blue;
+      essentials->ch_fg[AT_ZV].red = odd_at_zv_fg.red;
+      essentials->ch_fg[AT_ZV].green = odd_at_zv_fg.green;
+      essentials->ch_fg[AT_ZV].blue = odd_at_zv_fg.blue;
+      essentials->ch_fg[POST_ZV].red = odd_post_zv_fg.red;
+      essentials->ch_fg[POST_ZV].green = odd_post_zv_fg.green;
+      essentials->ch_fg[POST_ZV].blue = odd_post_zv_fg.blue;
+    }
+    /* yellow */
+    else if ((!fill_column_p
+              && current_col % 2 == 0)
+             || (fill_column_p
+                 && current_col % 2 == 0
+                 && current_col <= fill_col))
+      {
+        essentials->ch_fg[PRE_ZV].red = even_pre_zv_fg.red;
+        essentials->ch_fg[PRE_ZV].green = even_pre_zv_fg.green;
+        essentials->ch_fg[PRE_ZV].blue = even_pre_zv_fg.blue;
+        essentials->ch_fg[AT_ZV].red = even_at_zv_fg.red;
+        essentials->ch_fg[AT_ZV].green = even_at_zv_fg.green;
+        essentials->ch_fg[AT_ZV].blue = even_at_zv_fg.blue;
+        essentials->ch_fg[POST_ZV].red = even_post_zv_fg.red;
+        essentials->ch_fg[POST_ZV].green = even_post_zv_fg.green;
+        essentials->ch_fg[POST_ZV].blue = even_post_zv_fg.blue;
+      }
+      /* green */
+      else if (fill_column_p
+               && current_col > fill_col)
+        {
+          essentials->ch_fg[PRE_ZV].red = post_fill_pre_zv_fg.red;
+          essentials->ch_fg[PRE_ZV].green = post_fill_pre_zv_fg.green;
+          essentials->ch_fg[PRE_ZV].blue = post_fill_pre_zv_fg.blue;
+          essentials->ch_fg[AT_ZV].red = post_fill_at_zv_fg.red;
+          essentials->ch_fg[AT_ZV].green = post_fill_at_zv_fg.green;
+          essentials->ch_fg[AT_ZV].blue = post_fill_at_zv_fg.blue;
+          essentials->ch_fg[POST_ZV].red = post_fill_post_zv_fg.red;
+          essentials->ch_fg[POST_ZV].green = post_fill_post_zv_fg.green;
+          essentials->ch_fg[POST_ZV].blue = post_fill_post_zv_fg.blue;
+        }
+}
+
+void
+mc_color_picker (struct window *w, struct glyph *glyph, struct mc_essentials essentials,
+                    struct mc_RGB *lsl_fg, int posint, enum mc_cursor_type cursor_type,
+                    enum mc_row_position row_position, enum mc_engine_type action_type)
+{
+  switch (action_type)
+  {
+    case MULTIPLE_CURSORS:
+    {
+      struct frame *f = XFRAME (w->frame);
+      ptrdiff_t current_col = mc_current_column (w, posint);
+      Lisp_Object buf = w->contents;
+      CHECK_BUFFER (buf);
+      struct buffer *b = XBUFFER (buf);
+      bool fill_column_p = !NILP (BVAR (b, fill_column));
+      int fill_col = (fill_column_p)
+                     ? XFIXNUM (BVAR (b, fill_column))
+                     : 0;
+      enum face_id even_face_id =
+        (!essentials.active_p
+         && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+        ? lookup_named_face (w, f, intern ("+-even-inactive-pre-zv-face"), true)
+        : lookup_named_face (w, f, intern ("+-even-pre-zv-face"), true);
+      struct face *even_face = FACE_FROM_ID (f, even_face_id);
+      Lisp_Object even_color = even_face->lface[LFACE_FOREGROUND_INDEX];
+      struct mc_RGB even_foreground;
+      mc_xw_color_values (w, even_color, &even_foreground);
+      enum face_id odd_face_id =
+        (!essentials.active_p
+         && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+        ? lookup_named_face (w, f, intern ("+-odd-inactive-pre-zv-face"), true)
+        : lookup_named_face (w, f, intern ("+-odd-pre-zv-face"), true);
+      struct face *odd_face = FACE_FROM_ID (f, odd_face_id);
+      Lisp_Object odd_color = odd_face->lface[LFACE_FOREGROUND_INDEX];
+      struct mc_RGB odd_foreground;
+      mc_xw_color_values (w, odd_color, &odd_foreground);
+      enum face_id beyond_fill_face_id =
+        (!essentials.active_p
+         && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+        ? lookup_named_face (w, f, intern ("+-post-fill-inactive-pre-zv-face"), true)
+        : lookup_named_face (w, f, intern ("+-post-fill-pre-zv-face"), true);
+      struct face *beyond_fill_face = FACE_FROM_ID (f, beyond_fill_face_id);
+      Lisp_Object beyond_fill_color = beyond_fill_face->lface[LFACE_FOREGROUND_INDEX];
+      struct mc_RGB beyond_fill_foreground;
+      mc_xw_color_values (w, beyond_fill_color, &beyond_fill_foreground);
+      /* red */
+      if ((!fill_column_p
+           && current_col % 2 != 0
+           && row_position == PRE_ZV)
+          || (fill_column_p
+              && current_col % 2 != 0
+              && current_col <= fill_col
+              && row_position == PRE_ZV))
+        {
+          lsl_fg->red = odd_foreground.red;
+          lsl_fg->green = odd_foreground.green;
+          lsl_fg->blue = odd_foreground.blue;
+        }
+        /* yellow */
+        else if ((!fill_column_p
+                  && current_col % 2 == 0
+                  && row_position == PRE_ZV)
+                 || (fill_column_p
+                     && current_col % 2 == 0
+                     && current_col <= fill_col
+                     && row_position == PRE_ZV))
+          {
+            lsl_fg->red = even_foreground.red;
+            lsl_fg->green = even_foreground.green;
+            lsl_fg->blue = even_foreground.blue;
+          }
+          /* green */
+          else if (fill_column_p
+                   && current_col > fill_col
+                   && row_position == PRE_ZV)
+            {
+              lsl_fg->red = beyond_fill_foreground.red;
+              lsl_fg->green = beyond_fill_foreground.green;
+              lsl_fg->blue = beyond_fill_foreground.blue;
+            }
+            else if (row_position == AT_ZV)
+              {
+                lsl_fg->red = essentials.sp_fg.red;
+                lsl_fg->green = essentials.sp_fg.green;
+                lsl_fg->blue = essentials.sp_fg.blue;
+              }
+      break;
+    }
+    case HORIZONTAL_RULER:
+    {
+      if (glyph != NULL
+          && glyph->u.ch == 95
+          && cursor_type == MC_HBAR)
+        {
+          lsl_fg->red = essentials.sp_fg.red;
+          lsl_fg->green = essentials.sp_fg.green;
+          lsl_fg->blue = essentials.sp_fg.blue;
+        }
+        else
+          {
+            lsl_fg->red = essentials.ch_fg[row_position].red;
+            lsl_fg->green = essentials.ch_fg[row_position].green;
+            lsl_fg->blue = essentials.ch_fg[row_position].blue;
+          }
+      break;
+    }
+    case VERTICAL_RULER:
+    {
+      lsl_fg->red = essentials.ch_fg[row_position].red;
+      lsl_fg->green = essentials.ch_fg[row_position].green;
+      lsl_fg->blue = essentials.ch_fg[row_position].blue;
+      break;
+    }
+    case FILL_COLUMN:
+    {
+      lsl_fg->red = essentials.fc_fg[row_position].red;
+      lsl_fg->green = essentials.fc_fg[row_position].green;
+      lsl_fg->blue = essentials.fc_fg[row_position].blue;
+      break;
+    }
+    case CURSOR_INDICATOR:
+    {
+      struct frame *f = XFRAME (w->frame);
+      enum face_id cursor_face_id =
+        (!essentials.active_p
+         && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows))
+         && row_position == PRE_ZV)
+          ? lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-pre-zv-face"), true)
+        : (essentials.active_p
+           && row_position == PRE_ZV)
+          ? lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-face"), true)
+        : (!essentials.active_p
+           && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows))
+           && row_position == AT_ZV)
+            ? lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-at-zv-face"), true)
+        : (essentials.active_p
+           && row_position == AT_ZV)
+          ? lookup_named_face (w, f, intern ("+-real-fake-cursor-at-zv-face"), true)
+        : lookup_named_face (w, f, intern ("+-real-fake-cursor-at-zv-face"), true);
+      struct face *cursor_face = FACE_FROM_ID (f, cursor_face_id);
+      Lisp_Object cursor_color = cursor_face->lface[LFACE_FOREGROUND_INDEX];
+      mc_xw_color_values (w, cursor_color, lsl_fg);
+      break;
+    }
+  }
+}
+
+/* Draw glyphs between START and END in AREA of ROW on window W,
+   starting at x-position X.  X is relative to AREA in W.  HL is a
+   face-override with the following meaning:
+   -  DRAW_NORMAL_TEXT  draw normally
+   -  DRAW_CURSOR    draw in cursor face
+   -  DRAW_MOUSE_FACE  draw in mouse face.
+   -  DRAW_INVERSE_VIDEO  draw in mode line face
+   -  DRAW_IMAGE_SUNKEN  draw an image with a sunken relief around it
+   -  DRAW_IMAGE_RAISED  draw an image with a raised relief around it
+   If OVERLAPS is non-zero, draw only the foreground of characters and
+   clip to the physical height of ROW.  Non-zero value also defines
+   the overlapping part to be drawn:
+   -  OVERLAPS_PRED    overlap with preceding rows
+   -  OVERLAPS_SUCC    overlap with succeeding rows
+   -  OVERLAPS_BOTH    overlap with both preceding/succeeding rows
+   -  OVERLAPS_ERASED_CURSOR  overlap with erased cursor area
+   Value is the x-position reached, relative to AREA of W. */
+int
+mc_draw_glyphs (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                int x, enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
+                enum draw_glyphs_face hl, int overlaps, int vpos, struct mc_RGB lsl,
+                enum mc_flavor glyph_flavor, enum mc_cursor_type cursor_type,
+                int wd, bool active_p, bool cursor_gc_p,
+                enum draw_glyph_action action_type, bool draw_p)
+{
+  int start_x = x;
+  int relative_x = 0;
+  int length = 0;
+  //  int start_hpos = start;
+  //  int end_hpos = end;
+  //  TRACE ((stderr, "mc_draw_glyphs (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+  //                  vpos, start_x, start_hpos, end_hpos));
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct glyph_string *head, *tail;
+  struct glyph_string *s;
+  struct glyph_string *clip_head = NULL, *clip_tail = NULL;
+  int i, j, x_reached, last_x, area_left = 0;
+  MC_DECLARE_HDC (hdc);
+  MC_ALLOCATE_HDC (hdc, f);
+  /* Let's rather be paranoid than getting a SEGV. */
+  end = min (end, row->used[area]);
+  start = clip_to_bounds (0, start, end);
+  /* Translate X to frame coordinates.  Set last_x to the right
+     end of the drawing area. */
+  if (row->full_width_p)
+    {
+      /* X is relative to the left edge of W, without scroll bars
+   or fringes. */
+      area_left = WINDOW_LEFT_EDGE_X (w);
+      last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
+                - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
+    }
+    else
+      {
+        area_left = window_box_left (w, area);
+        last_x = area_left + window_box_width (w, area);
+      }
+  x += area_left;
+  /* Build a doubly-linked list of glyph_string structures between
+     head and tail from what we have to draw.  Note that the macro
+     MC_BUILD_GLYPH_STRINGS will modify its start parameter.  That's
+     the reason we use a separate variable `i'. */
+  i = start;
+  USE_SAFE_ALLOCA;
+  MC_BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
+  if (tail)
+    {
+      s = glyph_string_containing_background_width (tail);
+      x_reached = s->x + s->background_width;
+    }
+    else
+      x_reached = x;
+  /* If there are any glyphs with lbearing < 0 or rbearing > width in
+     the row, redraw some glyphs in front or following the glyph
+     strings built above. */
+  if (head && !overlaps && row->contains_overlapping_glyphs_p)
+    {
+      struct glyph_string *h, *t;
+      Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+      int mouse_beg_col UNINIT, mouse_end_col UNINIT;
+      bool check_mouse_face = false;
+      int dummy_x = 0;
+      /* If mouse highlighting is on, we may need to draw adjacent
+   glyphs using mouse-face highlighting. */
+      if (area == TEXT_AREA && row->mouse_face_p
+          && hlinfo->mouse_face_beg_row >= 0
+          && hlinfo->mouse_face_end_row >= 0)
+        {
+          ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
+          if (row_vpos >= hlinfo->mouse_face_beg_row
+              && row_vpos <= hlinfo->mouse_face_end_row)
+            {
+              check_mouse_face = true;
+              mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
+                              ? hlinfo->mouse_face_beg_col
+                              : 0;
+              mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
+                              ? hlinfo->mouse_face_end_col
+                              : row->used[TEXT_AREA];
+            }
+        }
+      /* Compute overhangs for all glyph strings. */
+      if (FRAME_RIF (f)->compute_glyph_string_overhangs)
+        for (s = head; s; s = s->next)
+          FRAME_RIF (f)->compute_glyph_string_overhangs (s);
+      /* Prepend glyph strings for glyphs in front of the first glyph
+      string that are overwritten because of the first glyph
+      string's left overhang.  The background of all strings
+      prepended must be drawn because the first glyph string
+      draws over it. */
+      i = left_overwritten (head);
+      if (i >= 0)
+        {
+          enum draw_glyphs_face overlap_hl;
+          /* If this row contains mouse highlighting, attempt to draw
+             the overlapped glyphs with the correct highlight.  This
+             code fails if the overlap encompasses more than one glyph
+             and mouse-highlight spans only some of these glyphs.
+             However, making it work perfectly involves a lot more
+             code, and I don't know if the pathological case occurs in
+             practice, so we'll stick to this for now.  --- cyd  */
+          if (check_mouse_face
+              && mouse_beg_col < start && mouse_end_col > i)
+            overlap_hl = DRAW_MOUSE_FACE;
+            else
+              overlap_hl = DRAW_NORMAL_TEXT;
+          if (hl != overlap_hl)
+            clip_head = head;
+          j = i;
+          MC_BUILD_GLYPH_STRINGS (j, start, h, t, overlap_hl, dummy_x, last_x);
+          /* The `left_overwritten` behavior that erases the fake cursors traces to
+          `font->driver->draw` in `ns_draw_glyph_string'; and, the height of the rectangle
+          drawn by `ns_dumpglyphs_stretch'; and, `ns_maybe_dumpglyphs_background' which
+          erases the applicable rectangle. */
+          /* EXAMPLE:  	M
+          In this example, we have a visible 187 (») that is followed by a visible
+          TAB_STRETCH (as a result of a corresponding `buffer-display-table' entry),
+          followed by wide "M", followed by a space at the end of the glyph row
+          (which has no buffer position).  When placing a fake cursor on the "M",
+          hl == DRAW_CURSOR and the STRETCH_GLYPH is `left_overwritten`.  Drawing
+          normal text during `update_window' (DRAW_NORMAL_TEXT) can also erase fake
+          cursors that are `left_overwritten'. */
+          length = 0;
+          for (s = h; s; s = s->next)
+            {
+              s->left_overwritten_p = true;
+              s->action_type = action_type;
+              length += s->first_glyph->pixel_width;
+            }
+          relative_x = start_x - length;
+          for (s = h; s; s = s->next)
+            {
+              s->first_glyph->relative_x = relative_x;
+              relative_x += s->first_glyph->pixel_width;
+            }
+          start = i;
+          compute_overhangs_and_x (t, head->x, true);
+          prepend_glyph_string_lists (&head, &tail, h, t);
+          if (clip_head == NULL)
+            clip_head = head;
+        }
+      /* Prepend glyph strings for glyphs in front of the first glyph
+      string that overwrite that glyph string because of their
+      right overhang.  For these strings, only the foreground must
+      be drawn, because it draws over the glyph string at `head'.
+      The background must not be drawn because this would overwrite
+      right overhangs of preceding glyphs for which no glyph
+      strings exist. */
+      i = left_overwriting (head);
+      if (i >= 0)
+        {
+          enum draw_glyphs_face overlap_hl;
+          if (check_mouse_face
+              && mouse_beg_col < start && mouse_end_col > i)
+            overlap_hl = DRAW_MOUSE_FACE;
+            else
+              overlap_hl = DRAW_NORMAL_TEXT;
+          if (hl == overlap_hl || clip_head == NULL)
+            clip_head = head;
+          MC_BUILD_GLYPH_STRINGS (i, start, h, t, overlap_hl, dummy_x, last_x);
+          for (s = h; s; s = s->next)
+            s->background_filled_p = true;
+          compute_overhangs_and_x (t, head->x, true);
+          prepend_glyph_string_lists (&head, &tail, h, t);
+        }
+      /* Append glyphs strings for glyphs following the last glyph
+      string tail that are overwritten by tail.  The background of
+      these strings has to be drawn because tail's foreground draws
+      over it. */
+      i = right_overwritten (tail);
+      if (i >= 0)
+        {
+          enum draw_glyphs_face overlap_hl;
+          if (check_mouse_face
+              && mouse_beg_col < i && mouse_end_col > end)
+            overlap_hl = DRAW_MOUSE_FACE;
+            else
+              overlap_hl = DRAW_NORMAL_TEXT;
+          if (hl != overlap_hl)
+            clip_tail = tail;
+          MC_BUILD_GLYPH_STRINGS (end, i, h, t, overlap_hl, x, last_x);
+        /* The `right_overwritten` behavior that erases the fake cursors traces to
+        `font->driver->draw` in `ns_draw_glyph_string'; and, the height of the rectangle
+        drawn by `ns_dumpglyphs_stretch'; and, `ns_maybe_dumpglyphs_background' which
+        erases the applicable rectangle. */
+        /* EXAMPLE:  "Emacs Guided Tour	Overview".
+        right_overwritten (GNU Emacs welcome screen without `buffer-display-table')
+        and the real fake cursor is to the immediate right of the word "Tour": */
+        relative_x = start_x;
+        for (s = h; s; s = s->next)
+          {
+            s->right_overwritten_p = true;
+            s->action_type = action_type;
+            relative_x += s->first_glyph->pixel_width;
+            s->first_glyph->relative_x = relative_x;
+          }
+          /* Because MC_BUILD_GLYPH_STRINGS updates the first argument,
+          we don't have `end = i;' here. */
+          compute_overhangs_and_x (h, tail->x + tail->width, false);
+          append_glyph_string_lists (&head, &tail, h, t);
+          if (clip_tail == NULL)
+            clip_tail = tail;
+        }
+      /* Append glyph strings for glyphs following the last glyph
+      string tail that overwrite tail.  The foreground of such
+      glyphs has to be drawn because it writes into the background
+      of tail.  The background must not be drawn because it could
+      paint over the foreground of following glyphs. */
+      i = right_overwriting (tail);
+      if (i >= 0)
+        {
+          enum draw_glyphs_face overlap_hl;
+          if (check_mouse_face
+              && mouse_beg_col < i && mouse_end_col > end)
+            overlap_hl = DRAW_MOUSE_FACE;
+            else
+              overlap_hl = DRAW_NORMAL_TEXT;
+          if (hl == overlap_hl || clip_tail == NULL)
+            clip_tail = tail;
+          i++;      /* We must include the Ith glyph. */
+          MC_BUILD_GLYPH_STRINGS (end, i, h, t, overlap_hl, x, last_x);
+          for (s = h; s; s = s->next)
+            s->background_filled_p = true;
+          compute_overhangs_and_x (h, tail->x + tail->width, false);
+          append_glyph_string_lists (&head, &tail, h, t);
+        }
+      tail = glyph_string_containing_background_width (tail);
+      if (clip_tail)
+        clip_tail = glyph_string_containing_background_width (clip_tail);
+      if (clip_head || clip_tail)
+        for (s = head; s; s = s->next)
+          {
+            s->clip_head = clip_head;
+            s->clip_tail = clip_tail;
+          }
+    }
+  /* Draw all strings. */
+  for (s = head; s && draw_p; s = s->next)
+    FRAME_RIF (f)->mc_scribe_string (s, matrix, row, lsl, glyph_flavor,
+                                     cursor_type, wd, active_p, cursor_gc_p);
+#ifndef HAVE_NS
+  /* When focus a sole frame and move horizontally, this clears on_p
+     causing a failure to erase prev cursor position. */
+  if (area == TEXT_AREA
+      && !row->full_width_p
+      /* When drawing overlapping rows, only the glyph strings'
+      foreground is drawn, which doesn't erase a cursor completely. */
+      && !overlaps)
+    {
+      int x0 = clip_head ? clip_head->x : (head ? head->x : x);
+      int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
+                          : (tail ? tail->x + tail->background_width : x));
+      x0 -= area_left;
+      x1 -= area_left;
+      notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
+         row->y, MATRIX_ROW_BOTTOM_Y (row));
+    }
+#endif
+  /* Value is the x-position up to which drawn, relative to AREA of W.
+     This doesn't include parts drawn because of overhangs. */
+  if (row->full_width_p)
+    x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
+  else
+    x_reached -= area_left;
+  MC_RELEASE_HDC (hdc, f);
+  SAFE_FREE ();
+  return x_reached;
+}
+
+/* Draw the cursor glyph of window W in glyph row ROW.  See the
+   comment of draw_glyphs for the meaning of HL. */
+void
+mc_draw_cursor_glyph (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                      enum draw_glyphs_face hl, int x, int hpos, int vpos,
+                      struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+                      enum mc_cursor_type cursor_type, int wd, bool active_p,
+                      bool cursor_gc_p)
+{
+  //  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  //  fprintf (stderr, "mc_draw_cursor_glyph:  ch (%d) | x (%d), hpos (%d), vpos(%d), hl (%d)\n",
+  //                    cursor_glyph->u.ch, x, hpos, vpos, hl);
+  block_input ();
+  bool draw_p = true;
+  mc_draw_glyphs (w, matrix, row, x, TEXT_AREA, hpos, hpos + 1, hl, 0, vpos, lsl,
+                  glyph_flavor, cursor_type, wd, active_p, cursor_gc_p,
+                  MC_DRAW_GLYPH_STRING, draw_p);
+  unblock_input ();
+  /* When we erase the cursor, and ROW is overlapped by other rows, make
+  sure that these overlapping parts of other rows are redrawn. */
+  if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+    {
+      if (row > matrix->rows
+          && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
+        x_fix_overlapping_area (w, row - 1, TEXT_AREA, OVERLAPS_ERASED_CURSOR);
+      if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
+          && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
+        x_fix_overlapping_area (w, row + 1, TEXT_AREA, OVERLAPS_ERASED_CURSOR);
+    }
+}
+
+void
+mc_erase_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                 int x, int y, int hpos, int vpos, enum mc_flavor glyph_flavor,
+                 enum mc_cursor_type cursor_type, int wd)
+{
+  bool debug_p = false;
+  if (debug_p)
+    fprintf (stderr, "mc_erase_cursor:  x (%d) | y (%d) | hpos (%d) | vpos (%d) | wd (%d)\n\
+    glyph_flavor (%s) | cursor_type (%s)\n",
+    x, y, hpos, vpos, wd,
+    mc_flavor_to_string (glyph_flavor), mc_cursor_type_to_string (cursor_type));
+  struct frame *f = XFRAME (w->frame);
+  Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+  bool mouse_face_here_p = false;
+  struct glyph *cursor_glyph;
+  enum draw_glyphs_face hl;
+  /* No cursor displayed or row invalidated => nothing to do on the screen. */
+  if (cursor_type == MC_NO_CURSOR)
+    {
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 1);
+      return;
+    }
+  /* VPOS >= matrix->nrows means that window has been resized.
+     Don't bother to erase the cursor. */
+  if (vpos >= matrix->nrows)
+    {
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 2);
+      return;
+    }
+  /* If row containing cursor is marked invalid, there is nothing we
+     can do. */
+  if (!row->enabled_p)
+    {
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 3);
+      return;
+    }
+  /* If line spacing is > 0, old cursor may only be partially visible in
+     window after split-window.  So adjust visible height. */
+  row->visible_height = min (row->visible_height,
+            window_text_bottom_y (w) - 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 (row->visible_height <= 0)
+    {
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 4);
+      return;
+    }
+  /* If cursor is in the fringe, erase by drawing actual bitmap there. */
+  if (row->cursor_in_fringe_p
+      && glyph_flavor != MC_GLYPH)
+    {
+      row->cursor_in_fringe_p = false;
+      mc_draw_fringe_bitmap (w, row, row->reversed_p, cursor_type);
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 5);
+      return;
+    }
+  /* 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 ((row->reversed_p
+       ? (hpos < 0)
+       : (hpos >= row->used[TEXT_AREA])))
+    {
+      if (debug_p)
+        fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 6);
+      return;
+    }
+  /* 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 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. */
+      && row->used[TEXT_AREA] > hpos && hpos >= 0)
+    mouse_face_here_p = true;
+  /* Maybe clear the display under the cursor. */
+  if (cursor_type == MC_HOLLOW_BOX
+      || cursor_type == MC_FRAMED_BOX)
+    {
+      int temp_x = x;
+      int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+      cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+      if (cursor_glyph == NULL)
+        {
+          if (debug_p)
+            fprintf (stderr, "mc_erase_cursor:  return (%d)\n", 7);
+          return;
+        }
+      int temp_wd = cursor_glyph->pixel_width;
+      if (temp_x < 0)
+        {
+          temp_wd += temp_x;
+          temp_x = 0;
+        }
+      temp_wd = min (wd, window_box_width (w, TEXT_AREA) - temp_x);
+      int fy = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
+      int fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, temp_x);
+      if (temp_wd > 0)
+        FRAME_RIF (f)->clear_frame_area (f, fx, fy, temp_wd, 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;
+  struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+  bool active_p = false;
+  bool cursor_gc_p = false;
+  //  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  //  fprintf (stderr, "mc_draw_cursor_glyph:  ch (%d) | x (%d), hpos (%d), vpos(%d), hl (%d)\n",
+  //                    cursor_glyph->u.ch, x, hpos, vpos, hl);
+  block_input ();
+  bool draw_p = true;
+  mc_draw_glyphs (w, matrix, row, x, TEXT_AREA, hpos, hpos + 1, hl, 0,
+                  vpos, lsl, glyph_flavor, cursor_type, wd, active_p,
+                  cursor_gc_p, MC_ERASE_GLYPH_STRING, draw_p);
+  unblock_input ();
+  /* When we erase the cursor, and ROW is overlapped by other rows, make
+  sure that these overlapping parts of other rows are redrawn. */
+  if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+    {
+      if (row > matrix->rows
+          && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
+        x_fix_overlapping_area (w, row - 1, TEXT_AREA, OVERLAPS_ERASED_CURSOR);
+      if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
+          && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
+        x_fix_overlapping_area (w, row + 1, TEXT_AREA, OVERLAPS_ERASED_CURSOR);
+    }
+}
+
+/* We call this a draw/erase hybrid because it does all of the following:
+- Draw all glyph cursors, but erase with `mc_erase_cursor'.
+- Draw/erase all fringe bitmaps relating to crosshairs.
+- Draw/erase all glyphless cursors. */
+void
+mc_draw_erase_hybrid (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                      int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h,
+                      enum mc_cursor_type cursor_type, int cursor_width,
+                      struct mc_RGB lsl, bool active_p, enum mc_flavor glyph_flavor,
+                      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 = (matrix && matrix->rows) ? false : true;
+  if (barf_crash_one)
+    return;
+  bool barf_crash_two = (vpos >= 0 && vpos < 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);
+  int fringe_bitmap = MC_NO_FRINGE_BITMAP;
+  int face_id = DEFAULT_FACE_ID;
+  if (!remove_p
+      && glyph_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), ch_inactive_windows)))
+        ? lookup_named_face (w, f, intern ("+-overlay-arrow-inactive-pre-zv-face"), true)
+        : (active_p)
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-pre-zv-face"), true)
+        : DEFAULT_FACE_ID;
+      face_id = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                ? overlay_arrow_face_id
+                : DEFAULT_FACE_ID;
+      /* fringe_bitmap = mc_get_fringe_bitmap (w, Qoverlay_arrow, false, false); */
+      if (w->hscroll != 0)
+        fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-overlay-arrow"), false, true);
+        else
+          fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-overlay-arrow"), true, true);
+      /* As to `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-pre-zv-face '+-fringe-right-arrow '+-overlay-arrow-pre-zv-face)
+      If we use `row->left_fringe_bitmap`, then the face may be set using
+      BOTH the `face-remapping-alist' and `row->left_fringe_face_id`.  In
+      that situation, a Lisp setting of `set-fringe-bitmap-face' is not needed.
+      `mc_draw_fringe_bitmap_1' is somewhat confusing and required stderr messages
+      to see that `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'. */
+      row->left_fringe_bitmap = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                ? fringe_bitmap
+                                : MC_NO_FRINGE_BITMAP;
+      row->left_fringe_face_id = face_id;
+      row->left_fringe_offset = 0;
+      row->fringe_bitmap_periodic_p = false;
+      mc_draw_fringe_bitmap (w, row, true, cursor_type);
+    }
+    else if (!remove_p
+             && glyph_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), ch_inactive_windows)))
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-inactive-pre-zv-face"), true)
+          : (active_p)
+            ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-pre-zv-face"), true)
+          : DEFAULT_FACE_ID;
+        face_id = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                  ? overlay_arrow_face_id
+                  : DEFAULT_FACE_ID;
+        if (hscl_all_perm_0_p)
+          fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), false, false);
+          else if (hscl_all_perm_1_p)
+            fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), true, false);
+            else if (hscl_all_perm_2_p)
+              fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), false, true);
+              else if (hscl_perm_p)
+                fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-perm"), true, true);
+                else if (hscl_all_temp_p)
+                  fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-temp"), false, false);
+                  else if (hscl_temp_p)
+                    fringe_bitmap = mc_get_fringe_bitmap (w, intern ("+-hscl-temp"), true, false);
+        /* As to `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-pre-zv-face '+-fringe-right-arrow '+-overlay-arrow-pre-zv-face)
+        If we use `row->left_fringe_bitmap`, then the face may be set using
+        BOTH the `face-remapping-alist' and `row->left_fringe_face_id`.  In
+        that situation, a Lisp setting of `set-fringe-bitmap-face' is not needed.
+        `mc_draw_fringe_bitmap_1' is somewhat confusing and required stderr messages
+        to see that `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'. */
+        row->left_fringe_bitmap = (cursor_type == MC_LEFT_FRINGE_BITMAP)
+                                          ? fringe_bitmap
+                                          : MC_NO_FRINGE_BITMAP;
+        row->left_fringe_face_id = face_id;
+        row->left_fringe_offset = 0;
+        row->fringe_bitmap_periodic_p = false;
+        mc_draw_fringe_bitmap (w, row, true, cursor_type);
+      }
+      else if (!remove_p
+               && (glyph_flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   || glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                   || glyph_flavor == MC_HOLLOW_RECTANGLE
+                   || glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+                   || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                   || glyph_flavor == MC_VERTICAL_BAR
+                   || glyph_flavor == MC_REVERSED_VERTICAL_BAR
+                   || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH))
+        {
+          Lisp_Object bitmap_flavor = (glyph_flavor == MC_HOLLOW_RECTANGLE_RIGHT_ARROW)
+                                      ? Qmc_hollow_rectangle_right_arrow
+                                      : (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW)
+                                        ? Qmc_reversed_hollow_rectangle_right_arrow
+                                      : (glyph_flavor == MC_HOLLOW_RECTANGLE)
+                                        ? Qmc_hollow_rectangle
+                                      : (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW)
+                                        ? Qmc_vertical_bar_right_arrow
+                                      : (glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW)
+                                        ? Qmc_reversed_vertical_bar_right_arrow
+                                      : (glyph_flavor == MC_VERTICAL_BAR)
+                                        ? Qmc_vertical_bar
+                                      : (glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+                                        ? Qmc_reversed_vertical_bar
+                                      : (glyph_flavor == MC_VERTICAL_BAR_BACKSLASH)
+                                        ? Qmc_vertical_bar_backslash
+                                      : Qnil;
+          fringe_bitmap = (cursor_type == MC_RIGHT_FRINGE_BITMAP)
+                          ? lookup_fringe_bitmap (bitmap_flavor)
+                          : MC_NO_FRINGE_BITMAP;
+          face_id = (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                     && (glyph_flavor == MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                         || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                         || glyph_flavor == MC_REVERSED_VERTICAL_BAR))
+                      ? lookup_named_face (w, f, intern ("+-reversed-bar-pre-zv-face"), true)
+                    : (cursor_type == MC_RIGHT_FRINGE_BITMAP
+                       && glyph_flavor != MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW
+                       && glyph_flavor != MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                       && glyph_flavor != MC_REVERSED_VERTICAL_BAR)
+                      ? lookup_named_face (w, f, intern ("+-bar-pre-zv-face"), true)
+                    : DEFAULT_FACE_ID;
+          row->cursor_in_fringe_p = false;
+          row->right_fringe_bitmap = fringe_bitmap;
+          row->right_fringe_face_id = face_id;
+          row->right_fringe_offset = 0;
+          row->fringe_bitmap_periodic_p = false;
+          mc_draw_fringe_bitmap (w, row, false, cursor_type);
+        }
+        else if (glyph_flavor == MC_GLYPH
+                 || glyph_flavor == MC_GLYPHLESS)
+          {
+            bool on_p = true;
+            FRAME_RIF (f)->mc_scribe_cursor (w, matrix, row, x, fx, y, fy, hpos,
+                                             vpos, wd, h, lsl, cursor_type,
+                                             cursor_width, glyph_flavor, on_p,
+                                             active_p);
+          }
+}
+
+/* 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, int vpos)
+{
+  bool glyph_zv_p = (glyph - row->glyphs[area] == row->used[area] - 1
+                     && MATRIX_ROW_END_CHARPOS (row) == ZV);
+  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  %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->hpos, glyph_zv_p ? "ZV" : "--",
+        mc_char_to_string (glyph->u.ch));
+    }
+  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  %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->hpos, 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  %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->hpos, 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, "  %3d %s . [%d-%d]\n",
+                         glyph->hpos, 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  %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->hpos, 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)
+    {
+      for (int 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 HPOS ZV C\n");
+          for (; glyph < glyph_end; ++glyph)
+            {
+              mc_dump_glyph (row, glyph, area, relative_x, vpos);
+              relative_x += glyph->pixel_width;
+            }
+        }
+    }
+    else if (glyphs == 1)
+      {
+        char s[SHRT_MAX + 4];
+        for (int 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 = w->current_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);
+      }
+  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;
+}
+
+bool
+mc_traverse_cache_p (struct mc_matrix matrix, enum mc_cache_type cache_type,
+                     int vnth, int nth)
+{
+  if (vnth < matrix.vpos_used
+      && matrix.cursors_used[cache_type] > 0
+      && nth < matrix.vpos[vnth].cache_used[cache_type])
+    return true;
+    else
+      return false;
+}
+
+void
+mc_reset_cache (struct window *w)
+{
+  if (!BUFFERP (w->contents))
+    return;
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    {
+      bool bvar_active_p;
+      switch (cache_type)
+        {
+          case NO_CACHE:
+            {
+              return;
+            }
+          case MC_CACHE:
+            {
+              if (BUFFERP (w->contents)
+                  && NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+                bvar_active_p = false;
+                else if (BUFFERP (w->contents)
+                         && !NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+                  bvar_active_p = true;
+              break;
+            }
+          case CH_CACHE:
+            {
+              if (BUFFERP (w->contents)
+                  && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+                bvar_active_p = false;
+                else if (BUFFERP (w->contents)
+                         && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+                  bvar_active_p = true;
+              break;
+            }
+          case FC_CACHE:
+            {
+              if (BUFFERP (w->contents)
+                  && NILP (BVAR (XBUFFER (w->contents), fc_visible)))
+                bvar_active_p = false;
+                else if (BUFFERP (w->contents)
+                         && !NILP (BVAR (XBUFFER (w->contents), fc_visible)))
+                  bvar_active_p = true;
+              break;
+            }
+        }
+      if (!bvar_active_p)
+        {
+          /* Decrease the size of the array to a bare minimum. */
+          for (int vnth = 0; vnth < w->mc_matrix.vpos_used; ++vnth)
+            {
+              if (w->mc_matrix.vpos[vnth].cache_allocated[cache_type] > 1)
+                {
+                  w->mc_matrix.vpos[vnth].cache[cache_type] =
+                    xnrealloc (w->mc_matrix.vpos[vnth].cache[cache_type], 1,
+                               sizeof *w->mc_matrix.vpos[vnth].cache[cache_type]);
+                  w->mc_matrix.vpos[vnth].cache_allocated[cache_type] = 1;
+                }
+              w->mc_matrix.vpos[vnth].cache_used[cache_type] = 0;
+            }
+          w->mc_matrix.cursors_used[cache_type] = 0;
+        }
+        //  Although it would not be very efficient, it is possible to set
+        //  the _used_ elements of the array to zero.  In such a case, the
+        //  ..._elts.allocated[cache_type] would remain the same.
+        //  memset (w->mc_matrix.vpos[@].cache[cache_type], 0, w->mc_matrix.vpos[@].cache_used[cache_type]
+        //          * (sizeof *w->mc_matrix.vpos[@].cache[cache_type]));
+        //  At this time, we are instead leaving the array as-is with the
+        //  understanding that it will contain outdated data (aka garbage).
+        //  Using the counter `w->mc_matrix.vpos[@].cache_used[cache_type]`, we track current data.
+        else if (bvar_active_p)
+          {
+            for (int vnth = 0; vnth < w->mc_matrix.vpos_used; ++vnth)
+              w->mc_matrix.vpos[vnth].cache_used[cache_type] = 0;
+            w->mc_matrix.cursors_used[cache_type] = 0;
+          }
+    }
+}
+
+static void
+mc_helper (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+           struct glyph *glyph, int x, int fx, int y, int fy, int hpos, int vpos,
+           int wd, int h, enum mc_cursor_type cursor_type, int cursor_width,
+           struct mc_RGB foreground, struct mc_RGB background, bool active_p,
+           enum mc_flavor glyph_flavor, bool draw_p, enum mc_draw_row_type from_where,
+           enum mc_cache_type cache_type, enum mc_engine_type action_type)
+{
+  int vnth = MATRIX_ROW_VPOS (row, matrix);
+  if (mc_stderr_p
+      && draw_p)
+    {
+      int charpos = glyph->charpos;
+      fprintf (stderr, "\nmc_helper (%s):  from_where (%s)\n\
+  action_type (%s) | flavor (%s) | charpos (%d)\n\
+  char (%s) | x (%d) | fx (%d) | y (%d) | fy (%d) | hpos (%d/%d) | vpos (%d)\n\
+  h (%d) | cursor_type (%s) | cursor_width (%d) | active_p (%s)\n\
+  FG-RGB (%f/%f/%f) | BG-RGB (%f/%f/%f)\n",
+      mc_window (w), mc_draw_row_type_to_string (from_where),
+      mc_engine_type_to_string (action_type), mc_flavor_to_string (glyph_flavor),
+      charpos, mc_char_to_string (glyph->u.ch), x, fx, y, fy, hpos,
+      row->used[TEXT_AREA] - 1, vpos, h, mc_cursor_type_to_string (cursor_type),
+      cursor_width, (active_p ? "true" : "false"), foreground.red, foreground.green,
+      foreground.blue, background.red, background.green, background.blue);
+    }
+  bool remove_p = false;
+  if (draw_p
+      && (from_where == SKIPPED
+          || from_where == POST_CHANGED
+          || from_where == UNCHANGED
+          || from_where == SET_CURSOR_TWO))
+    {
+      bool same_p = false;
+      for (int nth = 0; nth < w->mc_matrix.vpos[vnth].cache_used[cache_type]; ++nth)
+        {
+          same_p |=
+            (w->mc_matrix.vpos[vnth].cache[cache_type][nth].same_p == true
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.type == glyph->type
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.bytepos == glyph->bytepos
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.charpos == glyph->charpos
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.u.val == glyph->u.val
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.face_id == glyph->face_id
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.padding_p == glyph->padding_p
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.left_box_line_p == glyph->left_box_line_p
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.right_box_line_p == glyph->right_box_line_p
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.voffset == glyph->voffset
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.pixel_width == glyph->pixel_width
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.x == glyph->slice.img.x
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.y == glyph->slice.img.y
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.width == glyph->slice.img.width
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.height == glyph->slice.img.height
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.cmp.from == glyph->slice.cmp.from
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].x == x
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].fx == fx
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].y == y
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].fy == fy
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].hpos == hpos
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].vpos == vpos
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].wd == wd
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].h == h
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_type == cursor_type
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_width == cursor_width
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.red == foreground.red
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.green == foreground.green
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.blue == foreground.blue
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.red == background.red
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.green == background.green
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.blue == background.blue
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].active_p == active_p
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph_flavor == glyph_flavor
+             && w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p == true);
+        }
+      if (!same_p)
+        mc_draw_erase_hybrid (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h, cursor_type,
+                              cursor_width, foreground, active_p, glyph_flavor, remove_p);
+      return;
+    }
+    else if (draw_p
+             && (from_where == SCRIBE_ONE
+                 || from_where == SCRIBE_TWO
+                 || from_where == SCRIBE_THREE
+                 || from_where == NOWHERE))
+      {
+        mc_draw_erase_hybrid (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h, cursor_type,
+                              cursor_width, foreground, active_p, glyph_flavor, remove_p);
+        return;
+      }
+  if (cache_type == NO_CACHE)
+    return;
+  ++w->mc_matrix.cursors_used[cache_type];
+  if (vnth >= w->mc_matrix.vpos_used)
+    w->mc_matrix.vpos_used = vnth + 1;
+  if (w->mc_matrix.vpos_allocated < w->mc_matrix.vpos_used)
+    {
+      int old_alloc = w->mc_matrix.vpos_allocated;
+      int new_elts = w->mc_matrix.vpos_used - w->mc_matrix.vpos_allocated;
+      w->mc_matrix.vpos = xpalloc (w->mc_matrix.vpos, &w->mc_matrix.vpos_allocated,
+                                   new_elts, INT_MAX, sizeof *w->mc_matrix.vpos);
+      memset (w->mc_matrix.vpos + old_alloc, 0,
+               (w->mc_matrix.vpos_allocated - old_alloc) * sizeof *w->mc_matrix.vpos);
+    }
+  ++w->mc_matrix.vpos[vnth].cache_used[cache_type];
+  if (w->mc_matrix.vpos[vnth].cache_allocated[cache_type] < w->mc_matrix.vpos[vnth].cache_used[cache_type])
+    {
+      int old_alloc = w->mc_matrix.vpos[vnth].cache_allocated[cache_type];
+      int new_elts = w->mc_matrix.vpos[vnth].cache_used[cache_type] - w->mc_matrix.vpos[vnth].cache_allocated[cache_type];
+      w->mc_matrix.vpos[vnth].cache[cache_type] = xpalloc (w->mc_matrix.vpos[vnth].cache[cache_type],
+                                                           &w->mc_matrix.vpos[vnth].cache_allocated[cache_type],
+                                                           new_elts,
+                                                           INT_MAX,
+                                                           sizeof *w->mc_matrix.vpos[vnth].cache[cache_type]);
+      memset (w->mc_matrix.vpos[vnth].cache[cache_type] + old_alloc, 0,
+               (w->mc_matrix.vpos[vnth].cache_allocated[cache_type] - old_alloc)
+                 * sizeof *w->mc_matrix.vpos[vnth].cache[cache_type]);
+    }
+  int nth = w->mc_matrix.vpos[vnth].cache_used[cache_type] - 1;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].same_p = false;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.type = glyph->type;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.bytepos = glyph->bytepos;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.charpos = glyph->charpos;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.u.val = glyph->u.val;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.u.ch = glyph->u.ch;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.face_id = glyph->face_id;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.padding_p = glyph->padding_p;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.left_box_line_p = glyph->left_box_line_p;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.right_box_line_p = glyph->right_box_line_p;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.voffset = glyph->voffset;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.pixel_width = glyph->pixel_width;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.x = glyph->slice.img.x;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.y = glyph->slice.img.y;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.width = glyph->slice.img.width;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.img.height = glyph->slice.img.height;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph.slice.cmp.from = glyph->slice.cmp.from;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].x = x;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].fx = fx;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].y = y;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].fy = fy;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].hpos = hpos;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].vpos = vpos;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].wd = wd;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].h = h;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_type = cursor_type;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_width = cursor_width;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.red = foreground.red;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.green = foreground.green;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.blue = foreground.blue;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.red = background.red;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.green = background.green;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.blue = background.blue;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].active_p = active_p;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph_flavor = glyph_flavor;
+  w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p = true;
+}
+
+/* Return a pointer to the glyph W's physical cursor is on.  Value is null if W's
+   matrix is invalid, so that no meaningful glyph can be returned. */
+struct glyph *
+mc_get_cursor_glyph (struct window *w, struct glyph_matrix *matrix,
+                     struct glyph_row *row, int hpos, int vpos)
+{
+  struct glyph *glyph;
+  if (!(vpos >= 0
+        && vpos < matrix->nrows))
+    return NULL;
+  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;
+}
+
+/* This function differs substantially from `get_phys_cursor_geometry'.
+   `xterm.c`:  `mc_x_draw_hollow_cursor` calls `x_draw_rectangle', which requires
+   a WD - 1 and H - 1.  So that `mc_get_cursor_geometry` can be used for all
+   platforms, `mc_x_draw_hollow_cursor` subtracts the extra pixel from WD and H.
+   FX:  Frame relative coordinate for window relative X.
+   FY:  Frame relative coordinate of ROW->Y; i.e., top of the line.  For an
+        MC_HBAR, use ROW->Y + ROW->VISIBLE_HEIGHT - 1 pixel so that it
+        is palced at the very bottom of the visible row.
+   WD:  GLYPH->PIXEL_WIDTH, except when dealing with a STRETCH_GLYPH when we take
+        into consideration `x-stretch-cursor' and `cursor_type`.
+   H:  MC_HBAR is 1 pixel, and all others are ROW->VISIBLE_HEIGHT.
+       FIXME:  Add conditions for user-specified thickness of MC_BAR and
+               MC_HBAR as to `mc-real-fake-cursor'.
+   MULTIPLE_CURSORS:  We do not use this function.
+   HORIZONTAL_RULER:  We want a universal FY coordinate for a level ruler.
+   VERTICAL_RULER and FILL_COLUMN:  We want an H that ensures no gap between the
+                                    previous/next line.  The FX coordinate is set
+                                    elsewhere:  `w->cursor.x` / `mc.fc_x`. */
+void
+mc_get_cursor_geometry (struct window *w, struct glyph_matrix *matrix,
+                        struct glyph_row *row, int x, int *fx, int y,
+                        int *fy, int hpos, int vpos, int *h,
+                        enum mc_cursor_type cursor_type, int cursor_width,
+                        int *wd)
+{
+  struct glyph *glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  if (glyph == NULL)
+    return;
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  *fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+  *h = row->visible_height;
+  /* Don't let the cursor exceed the dimensions of the row, so that
+  the upper/lower side of the box aren't clipped.  */
+  int w_header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+  int w_text_bottom_y = window_text_bottom_y (w) - *h;
+  if (y < w_header_line_height)
+    {
+      *h = max (*h - (w_header_line_height - y) + 1, *h);
+      y = w_header_line_height - 1;
+      // fprintf (stderr, "CONDITION # 1\n");
+    }
+   else if (y > w_text_bottom_y)
+     {
+       *h += y - w_text_bottom_y;
+       y = w_text_bottom_y;
+       // fprintf (stderr, "CONDITION # 2\n");
+     }
+  *fy = WINDOW_TO_FRAME_PIXEL_Y (w, y);
+  switch (cursor_type)
+    {
+      case MC_BAR:
+        {
+          if (cursor_width < 1)
+            cursor_width = max (FRAME_CURSOR_WIDTH (f), 1);
+          if (cursor_width < glyph->pixel_width)
+          *wd = cursor_width;
+          break;
+        }
+      case MC_HBAR:
+        {
+          int cursor_height = (cursor_width < 1) ? lrint (0.25 * *h) : cursor_width;
+          if (cursor_height > row->height)
+            cursor_height = row->height;
+          /* Cursor smaller than line height, so move down. */
+          if (*h > cursor_height)
+            *fy += *h - cursor_height;
+          *h = cursor_height;
+          *wd = glyph->pixel_width;
+          break;
+        }
+      case MC_RIGHT_FRINGE_BITMAP:
+      case MC_LEFT_FRINGE_BITMAP:
+      case MC_NO_FRINGE_BITMAP:
+      case MC_NO_CURSOR:
+      case MC_FRAMED_BOX:
+      case MC_FILLED_BOX:
+      case MC_HOLLOW_BOX:
+      default:
+      /* Compute the width of the rectangle to draw.  If on a stretch glyph, and
+      `x-stretch-cursor' is nil, don't draw a rectangle as wide as the glyph, but
+      use a canonical character width instead. */
+      *wd = (glyph->type == STRETCH_GLYPH
+             && !x_stretch_cursor_p)
+            ? min (FRAME_COLUMN_WIDTH (f), glyph->pixel_width)
+            : glyph->pixel_width;
+    }
+/*
+      fprintf (stderr, "cursor_width: (%d) | x (%d) | *fx (%d) | y (%d) | *fy (%d), *wd (%d) | *h (%d)\n",
+                       cursor_width, x, *fx, y, *fy, *wd, *h);
+*/
+}
+
+void
+mc_engine (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+           struct glyph *glyph, int area, int relative_x, int x_limit, int y,
+           int hpos, int vpos, enum mc_cursor_type cursor_type, int cursor_width,
+           struct glyph_matrix *cursor_matrix, struct mc_essentials essentials,
+           enum mc_row_position row_position, struct mc_RGB foreground,
+           enum mc_engine_type action_type, bool draw_p,
+           enum mc_draw_row_type from_where, enum mc_cache_type cache_type)
+{
+  int opoint_x = w->cursor.x;
+  int opoint_y = w->cursor.y;
+  int opoint_hpos = w->cursor.hpos;
+  int opoint_vpos = w->cursor.vpos;
+  int fx, fy, h, wd;
+  mc_get_cursor_geometry (w, matrix, row, relative_x, &fx, y, &fy, hpos, vpos,
+                          &h, cursor_type, cursor_width, &wd);
+  int opoint_fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, opoint_x);
+  int fc_fx = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, essentials.fc_x);
+  bool glyph_zv_p = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                     && MATRIX_ROW_END_CHARPOS (row) == ZV);
+  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);
+  struct glyph_row *cursor_row = (w->cursor.vpos != -1)
+                                 ? MATRIX_ROW (cursor_matrix, w->cursor.vpos)
+                                 : NULL;
+  struct glyph *cursor_glyph = (w->cursor.vpos != -1)
+                               ? mc_get_cursor_glyph (w, cursor_matrix, cursor_row,
+                                                      w->cursor.hpos, w->cursor.vpos)
+                               : NULL;
+  bool cursor_at_fringe_p = (cursor_glyph == NULL
+                             && cursor_row != NULL
+                             && w->cursor.hpos == cursor_row->used[TEXT_AREA]
+                             && cursor_row->exact_window_width_line_p
+                             && w->cursor.x == text_area_width
+                             && w->cursor.x == cursor_row->pixel_width);
+  bool cursor_beyond_fringe_p = (cursor_glyph == NULL
+                                 && cursor_row != NULL
+                                 && w->cursor.hpos == cursor_row->used[TEXT_AREA]
+                                 && !cursor_row->exact_window_width_line_p
+                                 && w->cursor.x >= text_area_width
+                                 && w->cursor.x >= cursor_row->pixel_width);
+  int frame_char_width = FRAME_COLUMN_WIDTH (f);
+  int temp_face_id = glyph->face_id;
+  struct mc_RGB background;
+  mc_set_lsl_bg (w, temp_face_id, &background);
+  bool real_fake_cursor_p = (opoint_x == relative_x
+                             && opoint_hpos == hpos
+                             && opoint_y == row->y
+                             && opoint_vpos == vpos);
+
+/* --------------------------------------------------------------------------- */
+/*                       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  %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->hpos, glyph_zv_p ? "ZV" : "--",
+        mc_char_to_string (glyph->u.ch));
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*               MULTIPLE_CURSORS:  CHAR_GLYPH | GLYPHLESS_GLYPH               */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               HORIZONTAL_RULER:  CHAR_GLYPH | GLYPHLESS_GLYPH               */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      if (relative_x < row->pixel_width
+          && !real_fake_cursor_p)
+        mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                   wd, h, cursor_type, cursor_width, foreground, background,
+                   essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                   action_type);
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && relative_x <= x_limit)
+        {
+          if (relative_x < row->pixel_width)
+            {
+              relative_x += glyph->pixel_width;
+              fx += glyph->pixel_width;
+            }
+          mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                     x_limit - relative_x, h, cursor_type, cursor_width,
+                     foreground, background, essentials.active_p, MC_GLYPHLESS,
+                     draw_p, from_where, cache_type, action_type);
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               VERTICAL_RULER:  CHAR_GLYPH | GLYPHLESS_GLYPH                 */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      enum mc_flavor glyph_flavor = (cursor_at_fringe_p
+                                     && row->continued_p)
+                                      ? MC_VERTICAL_BAR_BACKSLASH
+                                    : (cursor_at_fringe_p
+                                       && !row->continued_p
+                                       && !row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR
+                                    : (cursor_at_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && cursor_row->used[TEXT_AREA] != 1
+                                       && !row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR
+                                    : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                       && opoint_x >= row->pixel_width)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      if (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH
+          || glyph_flavor == MC_VERTICAL_BAR
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+        cursor_type = MC_RIGHT_FRINGE_BITMAP;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, relative_x, opoint_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*               FILL_COLUMN:  CHAR_GLYPH | GLYPHLESS_GLYPH                 */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      enum mc_flavor glyph_flavor = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                     && essentials.fc_x >= row->pixel_width)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : (!NILP (BVAR (b, crosshairs))
+                                       && !NILP (BVAR (XBUFFER (w->contents), ch_vertical_ruler))
+                                       && opoint_y == y
+                                       && opoint_vpos == vpos)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, relative_x, fc_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+    case CURSOR_INDICATOR:
+    {
+      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  %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->hpos, glyph_zv_p ? "ZV" : "--",
+        "\\S");
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                        HORIZONTAL_RULER:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      if (relative_x < row->pixel_width
+          && !real_fake_cursor_p)
+        mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                   wd, h, cursor_type, cursor_width, foreground, background,
+                   essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                   action_type);
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && relative_x <= x_limit)
+        {
+          if (relative_x < row->pixel_width)
+            relative_x += glyph->pixel_width;
+          temp_face_id = (row->fill_line_p)
+                         ? glyph->face_id
+                         : DEFAULT_FACE_ID;
+          struct mc_RGB background;
+          mc_set_lsl_bg (w, temp_face_id, &background);
+          mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                     x_limit - relative_x, h, cursor_type, x_limit - relative_x,
+                     foreground, background, essentials.active_p, MC_GLYPHLESS,
+                     draw_p, from_where, cache_type, action_type);
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          VERTICAL_RULER:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      if (row->fill_line_p
+          && glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && opoint_x > relative_x + glyph->pixel_width)
+        temp_face_id = glyph->face_id;
+        else if (!row->fill_line_p
+                 && glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                 && opoint_x > relative_x + glyph->pixel_width)
+          temp_face_id = DEFAULT_FACE_ID;
+      struct mc_RGB background;
+      mc_set_lsl_bg (w, temp_face_id, &background);
+      enum mc_flavor glyph_flavor = (cursor_at_fringe_p
+                                     && row->continued_p)
+                                      ? MC_VERTICAL_BAR_BACKSLASH
+                                    : (cursor_at_fringe_p
+                                       && !row->continued_p
+                                       && !row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR
+                                    : (cursor_at_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && cursor_row->used[TEXT_AREA] != 1
+                                       && !row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR
+                                    : MC_GLYPHLESS;
+      if (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH
+          || glyph_flavor == MC_VERTICAL_BAR
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+        cursor_type = MC_RIGHT_FRINGE_BITMAP;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, opoint_x, opoint_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where,
+                 cache_type, action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           FILL_COLUMN:  STRETCH_GLYPH                       */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      if (row->fill_line_p
+          && glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && essentials.fc_x > relative_x + glyph->pixel_width)
+        temp_face_id = glyph->face_id;
+        else if (!row->fill_line_p
+                 && glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                 && essentials.fc_x > relative_x + glyph->pixel_width)
+          temp_face_id = DEFAULT_FACE_ID;
+      struct mc_RGB background;
+      mc_set_lsl_bg (w, temp_face_id, &background);
+      enum mc_flavor glyph_flavor = MC_GLYPHLESS;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, essentials.fc_x, fc_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+    case CURSOR_INDICATOR:
+    {
+      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  %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->hpos, glyph_zv_p ? "ZV" : "--",
+        '.');
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                         MULTIPLE_CURSORS:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      cursor_type = MC_HOLLOW_BOX;
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                         HORIZONTAL_RULER:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      cursor_type = MC_HOLLOW_BOX;
+      if (!real_fake_cursor_p)
+        mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                   wd, h, cursor_type, cursor_width, foreground, background,
+                   essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                   action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           VERTICAL_RULER:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      cursor_type = MC_HOLLOW_BOX;
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                            FILL_COLUMN:  IMAGE_GLYPH                        */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      cursor_type = MC_HOLLOW_BOX;
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+    case CURSOR_INDICATOR:
+    {
+      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, "  %3d %s . [%d-%d]\n",
+                         glyph->hpos, 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, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                       HORIZONTAL_RULER:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      if (relative_x <= x_limit
+          && !real_fake_cursor_p)
+        mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                   wd, h, cursor_type, cursor_width, foreground, background,
+                   essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                   action_type);
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && relative_x <= x_limit)
+        {
+          relative_x += glyph->pixel_width;
+          while (relative_x <= x_limit)
+            {
+              mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                         wd, h, cursor_type, cursor_width, foreground, background,
+                         essentials.active_p, MC_GLYPHLESS, draw_p, from_where,
+                         cache_type, action_type);
+              relative_x += frame_char_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                         VERTICAL_RULER:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      enum mc_flavor glyph_flavor = (cursor_at_fringe_p
+                                     && row->continued_p)
+                                      ? MC_VERTICAL_BAR_BACKSLASH
+                                    : (cursor_at_fringe_p
+                                       && !row->continued_p
+                                       && !row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR
+                                    : (cursor_at_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && cursor_row->used[TEXT_AREA] != 1
+                                       && !row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR
+                                    : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                       && opoint_x >= row->pixel_width)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      if (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH
+          || glyph_flavor == MC_VERTICAL_BAR
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+        cursor_type = MC_RIGHT_FRINGE_BITMAP;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, relative_x, opoint_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where,
+                 cache_type, action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          FILL_COLUMN:  COMPOSITE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      enum mc_flavor glyph_flavor = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                     && essentials.fc_x > relative_x)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : (!NILP (BVAR (b, crosshairs))
+                                       && !NILP (BVAR (XBUFFER (w->contents), ch_vertical_ruler))
+                                       && opoint_y == y
+                                       && opoint_vpos == vpos)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      wd = 1;
+      mc_helper (w, matrix, row, glyph, relative_x, fc_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+    case CURSOR_INDICATOR:
+    {
+      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  %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->hpos, glyph_zv_p ? "ZV" : "--",
+        '.');
+#endif
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                 action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                        HORIZONTAL_RULER:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case HORIZONTAL_RULER:
+    {
+      if (relative_x <= x_limit
+          && !real_fake_cursor_p)
+        mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                   wd, h, cursor_type, cursor_width, foreground, background,
+                   essentials.active_p, MC_GLYPH, draw_p, from_where, cache_type,
+                   action_type);
+      if (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && relative_x <= x_limit)
+        {
+          relative_x += glyph->pixel_width;
+          while (relative_x <= x_limit)
+            {
+              mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                         wd, h, cursor_type, cursor_width, foreground, background,
+                         essentials.active_p, MC_GLYPHLESS, draw_p, from_where,
+                         cache_type, action_type);
+              relative_x += frame_char_width;
+            }
+        }
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          VERTICAL_RULER:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case VERTICAL_RULER:
+    {
+      enum mc_flavor glyph_flavor = (cursor_at_fringe_p
+                                     && row->continued_p)
+                                      ? MC_VERTICAL_BAR_BACKSLASH
+                                    : (cursor_at_fringe_p
+                                       && !row->continued_p
+                                       && !row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR
+                                    : (cursor_at_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+                                    : (cursor_beyond_fringe_p
+                                       && cursor_row->used[TEXT_AREA] != 1
+                                       && !row->truncated_on_right_p)
+                                      ? MC_REVERSED_VERTICAL_BAR
+                                    : (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                       && opoint_x >= row->pixel_width)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      if (glyph_flavor == MC_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR_RIGHT_ARROW
+          || glyph_flavor == MC_VERTICAL_BAR_BACKSLASH
+          || glyph_flavor == MC_VERTICAL_BAR
+          || glyph_flavor == MC_REVERSED_VERTICAL_BAR)
+        cursor_type = MC_RIGHT_FRINGE_BITMAP;
+      mc_helper (w, matrix, row, glyph, relative_x, opoint_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where,
+                 cache_type, action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           FILL_COLUMN:  XWIDGET_GLYPH                       */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      enum mc_flavor glyph_flavor = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                                     && essentials.fc_x > relative_x)
+                                      ? MC_GLYPHLESS
+                                    : (glyph_zv_p)
+                                      ? MC_GLYPHLESS
+                                    : (!NILP (BVAR (b, crosshairs))
+                                       && !NILP (BVAR (XBUFFER (w->contents), ch_vertical_ruler))
+                                       && opoint_y == y
+                                       && opoint_vpos == vpos)
+                                      ? MC_GLYPHLESS
+                                    : MC_GLYPH;
+      mc_helper (w, matrix, row, glyph, relative_x, fc_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 essentials.active_p, glyph_flavor, draw_p, from_where,
+                 cache_type, action_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+    case CURSOR_INDICATOR:
+    {
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                               END:  XWIDGET_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+}
+
+void
+mc_draw_row (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+             struct glyph *start, int x, int hpos_length, int vpos,
+             struct glyph_matrix *cursor_matrix, struct mc_essentials essentials,
+             enum mc_row_position row_position, bool draw_p, enum mc_draw_row_type from_where)
+{
+  //  clock_t clock_start = clock();
+  /* W32 Emacs crashes on startup without a `BUFFERP' check in `update_window'. */
+  if (!BUFFERP (w->contents))
+    return;
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  if (NILP (BVAR (b, mc_conf))
+      && NILP (BVAR (b, crosshairs))
+      && NILP (BVAR (b, fc_visible)))
+    return;
+  struct glyph_row *bottom_row = MATRIX_BOTTOM_TEXT_ROW (matrix, w);
+  int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, matrix);
+  if (vpos == bottom_vpos)
+    return;
+  if (!row->used[TEXT_AREA])
+    return;
+  int hpos_start = start - row->glyphs[TEXT_AREA];
+  if (trace_redisplay_p)
+    fprintf (stderr, "mc_draw_row (%d):  draw_p (%s) | hpos (%d) | len (%d)\n",
+                     vpos, draw_p ? "y" : "n", hpos_start, hpos_length);
+  int opoint_fx, opoint_fy, opoint_wd, opoint_h;
+  int text_area_width = window_box_width (w, TEXT_AREA);
+  int header_line_format = WINDOW_HEADER_LINE_HEIGHT (w);
+  struct glyph_row *cursor_row = (w->cursor.vpos != -1)
+                                 ? MATRIX_ROW (cursor_matrix, w->cursor.vpos)
+                                 : NULL;
+  struct glyph *cursor_glyph = (w->cursor.vpos != -1)
+                               ? mc_get_cursor_glyph (w, cursor_matrix, cursor_row,
+                                                      w->cursor.hpos, w->cursor.vpos)
+                               : NULL;
+  bool cursor_at_fringe_p = (cursor_glyph == NULL
+                             && cursor_row != NULL
+                             && w->cursor.hpos == cursor_row->used[TEXT_AREA]
+                             && cursor_row->exact_window_width_line_p
+                             && w->cursor.x == text_area_width
+                             && w->cursor.x == cursor_row->pixel_width);
+  bool cursor_beyond_fringe_p = (cursor_glyph == NULL
+                                 && cursor_row != NULL
+                                 && w->cursor.hpos == cursor_row->used[TEXT_AREA]
+                                 && !cursor_row->exact_window_width_line_p
+                                 && w->cursor.x >= text_area_width
+                                 && w->cursor.x >= cursor_row->pixel_width);
+/* ******************************************************************************
+                          REPLACE THE REAL CURSOR
+****************************************************************************** */
+  enum face_id bg_face_id = (cursor_glyph != NULL)
+                            ? cursor_glyph->face_id
+                            : DEFAULT_FACE_ID;
+  struct mc_RGB cursor_bg;
+  mc_set_lsl_bg (w, bg_face_id, &cursor_bg);
+  /* FIXME:  Put in some code to default to MC_HOLLOW_BOX if the user has
+  unwittingly come up with some unacceptable form of unrecognized cursor type. */
+  Lisp_Object lisp_type = BVAR (b, mc_real_fake_cursor);
+  enum mc_cursor_type cursor_type = (CONSP (lisp_type))
+                                    ? mc_lisp_to_cursor_type (XCAR (lisp_type))
+                                    : mc_lisp_to_cursor_type (lisp_type);
+  int cursor_width = (CONSP (lisp_type))
+                     ? XFIXNUM (XCAR (XCDR (lisp_type)))
+                     : -1;
+  struct mc_RGB cursor_fg;
+  mc_color_picker (w, cursor_glyph, essentials, &cursor_fg, -1, cursor_type,
+                   row_position, CURSOR_INDICATOR);
+  bool fill_column_trumps_p = (!NILP (BVAR (b, ch_vertical_ruler))
+                               && !NILP (BVAR (b, fc_visible))
+                               && w->cursor.x == essentials.fc_x
+                               && !cursor_at_fringe_p
+                               && !cursor_beyond_fringe_p);
+  /* We use a test similar to the real fake cursor so that the fringe bitmap is
+  only drawn once per window. */
+  if (vpos == w->cursor.vpos
+      && hpos_start + hpos_length == row->used[TEXT_AREA]
+      && !NILP (BVAR (b, crosshairs))
+      && !NILP (BVAR (b, ch_horizontal_ruler)))
+    {
+      /* fringe bitmaps use face_id to set the foreground color.  The overlay-arrow
+      is presently the only situation where the `essentials.active_p` and `minimal_p` are
+      used to determine the applicable face_id. */
+      struct mc_RGB lsl_fg = {.red = -1.0,
+                              .green = -1.0,
+                              .blue = -1.0};
+      /* We use the first glyph in the row, with an X and HPOS of zero. */
+      mc_helper (w, matrix, row, row->glyphs[TEXT_AREA], 0, -1, w->cursor.y, -1,
+                 0, w->cursor.vpos, -1, -1, MC_LEFT_FRINGE_BITMAP, -1,
+                 lsl_fg, cursor_bg, essentials.active_p, MC_OVERLAY_ARROW_BITMAP, draw_p,
+                 from_where, CH_CACHE, CURSOR_INDICATOR);
+    }
+  if (cursor_at_fringe_p
+      && vpos == w->cursor.vpos
+      && w->cursor.hpos >= hpos_start
+      && w->cursor.hpos == hpos_start + hpos_length
+      && !NILP (BVAR (b, crosshairs))
+      && !NILP (BVAR (b, ch_horizontal_ruler)))
+    {
+      enum mc_flavor glyph_flavor = MC_HOLLOW_RECTANGLE;
+      struct glyph *glyph = row->glyphs[TEXT_AREA];
+      struct glyph *glyph_end = glyph + row->used[TEXT_AREA];
+      /* Glyph for a line end in text. */
+      if (glyph == glyph_end && glyph->charpos > 0)
+        ++glyph_end;
+      mc_helper (w, matrix, row, glyph_end - 1, w->cursor.x, -1, w->cursor.y, -1,
+                 w->cursor.hpos, w->cursor.vpos, -1, -1, MC_RIGHT_FRINGE_BITMAP,
+                 -1, cursor_fg, cursor_bg, essentials.active_p, glyph_flavor, draw_p,
+                 from_where, CH_CACHE, CURSOR_INDICATOR);
+    }
+  /* Cursor is beyond the right fringe; e.g., when right horizontal scrolling. */
+  else if (cursor_beyond_fringe_p
+           && vpos == w->cursor.vpos
+           && w->cursor.hpos >= hpos_start
+           && (hpos_start + hpos_length) == row->used[TEXT_AREA]
+           && !NILP (BVAR (b, crosshairs))
+           && !NILP (BVAR (b, ch_horizontal_ruler)))
+    {
+      enum mc_flavor glyph_flavor = MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW;
+      struct glyph *glyph = row->glyphs[TEXT_AREA];
+      struct glyph *glyph_end = glyph + row->used[TEXT_AREA];
+      /* Glyph for a line end in text. */
+      if (glyph == glyph_end && glyph->charpos > 0)
+        ++glyph_end;
+      mc_helper (w, matrix, row, glyph_end - 1, row->pixel_width, -1, w->cursor.y,
+                 -1, row->used[TEXT_AREA] - 1, w->cursor.vpos, -1, -1,
+                 MC_RIGHT_FRINGE_BITMAP, -1, cursor_fg, cursor_bg, essentials.active_p,
+                 glyph_flavor, draw_p, from_where, CH_CACHE, CURSOR_INDICATOR);
+    }
+  /* EXAMPLE (buffer-local):  (setq mc-real-fake-cursor nil/'no/"no") */
+  else if (!cursor_at_fringe_p
+           && cursor_glyph != NULL
+           && cursor_type == MC_NO_CURSOR
+           && vpos == w->cursor.vpos
+           && w->cursor.hpos >= hpos_start
+           && w->cursor.hpos < hpos_start + hpos_length)
+    {
+      /* When a user has not specified a value for `mc-real-fake-cursor', or the
+      value is `no` in the form of a symbol or string, then the default we use
+      an MC_BAR and an MC_HBAR -- both having a cursor_width of 1. */
+      mc_get_cursor_geometry (w, matrix, row, w->cursor.x, &opoint_fx, w->cursor.y,
+                              &opoint_fy, w->cursor.hpos, w->cursor.vpos, &opoint_h,
+                              MC_BAR, 1, &opoint_wd);
+      mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, opoint_fx, w->cursor.y,
+                 opoint_fy, w->cursor.hpos, w->cursor.vpos, opoint_wd, opoint_h,
+                 MC_BAR, 1, cursor_fg, cursor_bg, essentials.active_p, MC_GLYPHLESS,
+                 draw_p, from_where, NILP (BVAR (b, mc_conf))
+                                     ? CH_CACHE
+                                     : MC_CACHE, CURSOR_INDICATOR);
+      mc_get_cursor_geometry (w, matrix, row, w->cursor.x, &opoint_fx, w->cursor.y,
+                              &opoint_fy, w->cursor.hpos, w->cursor.vpos, &opoint_h,
+                              MC_HBAR, 1, &opoint_wd);
+      mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, opoint_fx, w->cursor.y,
+                 opoint_fy, w->cursor.hpos, w->cursor.vpos, opoint_wd, opoint_h,
+                 MC_HBAR, 1, cursor_fg, cursor_bg, essentials.active_p, MC_GLYPH, draw_p,
+                 from_where, NILP (BVAR (b, mc_conf))
+                             ? CH_CACHE
+                             : MC_CACHE, CURSOR_INDICATOR);
+    }
+  else if (!cursor_at_fringe_p
+           && cursor_glyph != NULL
+           && vpos == w->cursor.vpos
+           && w->cursor.hpos >= hpos_start
+           && w->cursor.hpos < hpos_start + hpos_length
+           && cursor_glyph->type != STRETCH_GLYPH)
+    {
+      mc_get_cursor_geometry (w, matrix, row, w->cursor.x, &opoint_fx, w->cursor.y,
+                              &opoint_fy, w->cursor.hpos, w->cursor.vpos, &opoint_h,
+                              cursor_type, cursor_width, &opoint_wd);
+      mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, opoint_fx, w->cursor.y,
+                 opoint_fy, w->cursor.hpos, w->cursor.vpos, opoint_wd, opoint_h,
+                 cursor_type, cursor_width, cursor_fg, cursor_bg, essentials.active_p,
+                 MC_GLYPH, draw_p, from_where, NILP (BVAR (b, mc_conf))
+                                               ? CH_CACHE
+                                               : MC_CACHE, CURSOR_INDICATOR);
+    }
+  else if (!cursor_at_fringe_p
+           && cursor_glyph != NULL
+           && vpos == w->cursor.vpos
+           && w->cursor.hpos >= hpos_start
+           && w->cursor.hpos < hpos_start + hpos_length
+           && cursor_glyph->type == STRETCH_GLYPH)
+    {
+      /* If a user has set `x-stretch-cursor' to a non-nil value, he/she chose to
+      have a cursor that spans the entire length of the STRETCH_GLYPH. */
+      if (!x_stretch_cursor_p)
+        {
+          /* The MC_HBAR shall have a `cursor_width` of 1. */
+          mc_get_cursor_geometry (w, matrix, row, w->cursor.x, &opoint_fx,
+                                  w->cursor.y, &opoint_fy, w->cursor.hpos,
+                                  w->cursor.vpos, &opoint_h, MC_HBAR, 1,
+                                  &opoint_wd);
+          mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, opoint_fx,
+                     w->cursor.y, opoint_fy, w->cursor.hpos, w->cursor.vpos,
+                     opoint_wd, opoint_h, MC_HBAR, 1, cursor_fg, cursor_bg,
+                     essentials.active_p, MC_GLYPH, draw_p, from_where,
+                     NILP (BVAR (b, mc_conf))
+                     ? CH_CACHE
+                     : MC_CACHE, CURSOR_INDICATOR);
+        }
+      mc_get_cursor_geometry (w, matrix, row, w->cursor.x, &opoint_fx,
+                              w->cursor.y, &opoint_fy, w->cursor.hpos,
+                              w->cursor.vpos, &opoint_h, cursor_type,
+                              cursor_width, &opoint_wd);
+      mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, opoint_fx, w->cursor.y,
+                 opoint_fy, w->cursor.hpos, w->cursor.vpos, opoint_wd, opoint_h,
+                 cursor_type, cursor_width, cursor_fg, cursor_bg, essentials.active_p,
+                 MC_GLYPH, draw_p, from_where, NILP (BVAR (b, mc_conf))
+                                               ? CH_CACHE
+                                               : MC_CACHE, CURSOR_INDICATOR);
+    }
+/* ******************************************************************************
+                          DRAW AND RECORD FAKE CURSORS
+****************************************************************************** */
+  if (!essentials.active_p
+      && NILP (BVAR (b, mc_inactive_windows))
+      && NILP (BVAR (b, ch_inactive_windows))
+      && NILP (BVAR (b, fc_inactive_windows)))
+    return;
+  if (hpos_length == 1)
+    {
+      if (!NILP (BVAR (b, mc_conf))
+          && (essentials.active_p
+              || (!essentials.active_p
+                  && !NILP (BVAR (b, mc_inactive_windows)))))
+        {
+          /* 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. */
+          int hpos = start - row->glyphs[TEXT_AREA];
+          struct glyph *previous_glyph = (0 <= hpos - 1 && hpos - 1 < row->used[TEXT_AREA])
+                                         ? row->glyphs[TEXT_AREA] + hpos - 1
+                                         : NULL;
+          // struct glyph *last_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+          bool skip_p = (previous_glyph != NULL
+                         && previous_glyph->charpos == MATRIX_ROW_END_CHARPOS (row) - 1
+                         && start->bytepos != essentials.zv_byte)
+                          ? true
+                        /* When a `buffer-display-table' entry contains
+                        a visible tab character ("»"), the subsequent
+                        STRETCH_GLYPH will have the same start->charpos
+                        as the aforementioned visible tab character. */
+                        : (previous_glyph != NULL
+                           && previous_glyph->charpos == start->charpos)
+                          ? true
+                        : false;
+          int posint = (row_position == POST_ZV)
+                         ? -1
+                       : (row_position == AT_ZV)
+                          ? essentials.zv
+                       : (start->bytepos != essentials.zv_byte
+                          && start - row->glyphs[TEXT_AREA] == row->used[TEXT_AREA] - 1)
+                         ? MATRIX_ROW_END_CHARPOS (row) - 1
+                       : (start->bytepos == essentials.zv_byte
+                          && start - row->glyphs[TEXT_AREA] == row->used[TEXT_AREA] - 1)
+                         ? essentials.zv
+                       : start->charpos;
+          Lisp_Object specs = mc_assoc (make_fixnum (posint), BVAR (b, mc_conf));
+          if (((header_line_format > 0 && vpos > 0)
+               || header_line_format == 0)
+              && !NILP (specs)
+              && row->y <= window_text_bottom_y (w)
+              && !skip_p
+              && row_position != POST_ZV)
+            {
+              Lisp_Object lisp_type = mc_nth (1, specs);
+              enum mc_cursor_type cursor_type = (CONSP (lisp_type))
+                                                ? mc_lisp_to_cursor_type (XCAR (lisp_type))
+                                                : mc_lisp_to_cursor_type (lisp_type);
+              cursor_type = (start->type == IMAGE_GLYPH)
+                            ? MC_HOLLOW_BOX
+                            : cursor_type;
+              int cursor_width = (CONSP (lisp_type))
+                                 ? XFIXNUM (XCAR (XCDR (lisp_type)))
+                                 : -1;
+              Lisp_Object mc_foreground = mc_nth (2, specs);
+              struct mc_RGB lsl_fg;
+              if (STRINGP (mc_foreground))
+                mc_xw_color_values (w, mc_foreground, &lsl_fg);
+                else if (VECTORP (mc_foreground))
+                  {
+                    lsl_fg.red = XFLOAT_DATA (AREF (mc_foreground, 0));
+                    lsl_fg.green = XFLOAT_DATA (AREF (mc_foreground, 1));
+                    lsl_fg.blue = XFLOAT_DATA (AREF (mc_foreground, 2));
+                  }
+                  else if (NILP (mc_foreground))
+                    mc_color_picker (w, start, essentials, &lsl_fg, posint,
+                                     cursor_type, row_position, MULTIPLE_CURSORS);
+              int vpos = MATRIX_ROW_VPOS (row, matrix);
+              int x_limit = window_box_width (w, TEXT_AREA);
+              mc_engine (w, matrix, row, start, TEXT_AREA, x, x_limit, row->y,
+                         start - row->glyphs[TEXT_AREA], vpos, cursor_type,
+                         cursor_width, cursor_matrix, essentials, row_position,
+                         lsl_fg, MULTIPLE_CURSORS, draw_p, from_where, MC_CACHE);
+            }
+        }
+      if (!NILP (BVAR (b, fc_visible))
+          && (essentials.active_p
+              || (!essentials.active_p
+                  && !NILP (BVAR (b, fc_inactive_windows))))
+          && essentials.fc_x <= text_area_width
+          && essentials.fc_x >= w->mc.lnum_pixel_width)
+        {
+          int x_limit = x + start->pixel_width;
+          bool real_fake_cursor_p = (w->cursor.x == essentials.fc_x
+                                     && w->cursor.y == row->y
+                                     && w->cursor.hpos == start - row->glyphs[TEXT_AREA]
+                                     && w->cursor.vpos == vpos);
+          struct mc_RGB lsl_fg;
+          mc_color_picker (w, start, essentials, &lsl_fg, -1, MC_BAR,
+                           row_position, FILL_COLUMN);
+          if (x + start->pixel_width <= text_area_width
+              && ((header_line_format > 0 && vpos > 0)
+                  || header_line_format == 0)
+              && ((start != row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
+                   && essentials.fc_x >= x
+                   && essentials.fc_x < x + start->pixel_width)
+                  || (start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
+                      && essentials.fc_x >= x))
+              && row->y <= window_text_bottom_y (w)
+              && !real_fake_cursor_p)
+            mc_engine (w, matrix, row, start, TEXT_AREA, x, x_limit, row->y,
+                       start - row->glyphs[TEXT_AREA], vpos, MC_BAR, 1,
+                       cursor_matrix, essentials, row_position, lsl_fg,
+                       FILL_COLUMN, draw_p, from_where, FC_CACHE);
+        }
+      if (!NILP (BVAR (b, crosshairs))
+          && !NILP (BVAR (b, ch_horizontal_ruler))
+          && (essentials.active_p
+              || (!essentials.active_p
+                  && !NILP (BVAR (b, ch_inactive_windows))))
+          && vpos == w->cursor.vpos)
+        {
+          int x_limit = (start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1)
+                        ? text_area_width
+                        : x + start->pixel_width;
+          struct mc_RGB lsl_fg;
+          mc_color_picker (w, start, essentials, &lsl_fg, -1, MC_HBAR,
+                           row_position, HORIZONTAL_RULER);
+          /* Preserve support for default behavior such that a user may
+          specify the height of an MC_HBAR, which begins its journey
+          as the `cursor_width'.  `mc_get_cursor_geometry' readjusts. */
+          mc_engine (w, matrix, row, start, TEXT_AREA, x, x_limit, row->y,
+                     start - row->glyphs[TEXT_AREA], vpos, MC_HBAR, 1,
+                     cursor_matrix, essentials, row_position, lsl_fg,
+                     HORIZONTAL_RULER, draw_p, from_where, CH_CACHE);
+        }
+      if (!NILP (BVAR (b, crosshairs))
+          && !NILP (BVAR (b, ch_vertical_ruler))
+          && (essentials.active_p
+              || (!essentials.active_p
+                  && !NILP (BVAR (b, ch_inactive_windows))))
+          && !fill_column_trumps_p)
+        {
+          cursor_type = (start->type == IMAGE_GLYPH)
+                        ? MC_HOLLOW_BOX
+                        : MC_BAR;
+          int x_limit = window_box_width (w, TEXT_AREA);
+          bool real_fake_cursor_p = (w->cursor.y == row->y
+                                     && w->cursor.vpos == vpos);
+          struct mc_RGB lsl_fg;
+          mc_color_picker (w, start, essentials, &lsl_fg, -1, cursor_type,
+                           row_position, VERTICAL_RULER);
+          if (((header_line_format > 0 && vpos > 0)
+               || header_line_format == 0)
+              && ((start != row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
+                   && w->cursor.x >= x
+                   && w->cursor.x < x + start->pixel_width)
+                  || (start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
+                      && w->cursor.x >= x))
+              && row->y <= window_text_bottom_y (w)
+              && !real_fake_cursor_p)
+            mc_engine (w, matrix, row, start, TEXT_AREA, x, x_limit, row->y,
+                       start - row->glyphs[TEXT_AREA], vpos, cursor_type, 1,
+                       cursor_matrix, essentials, row_position, lsl_fg,
+                       VERTICAL_RULER, draw_p, from_where, CH_CACHE);
+        }
+    }
+    else
+      {
+        int relative_x = 0;
+        for (int 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;
+            for (; glyph < glyph_end; ++glyph)
+              {
+                if (vpos != w->cursor.vpos
+                    && glyph != glyph_end - 1
+                    && essentials.fc_x < relative_x
+                    && w->cursor.x < relative_x
+                    && NILP (BVAR (b, mc_conf)))
+                  break;
+                if (!NILP (BVAR (b, mc_conf))
+                    && (essentials.active_p
+                        || (!essentials.active_p
+                            && !NILP (BVAR (b, mc_inactive_windows)))))
+                  {
+                    /* 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 a `buffer-display-table' entry
+                    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. */
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    struct glyph *previous_glyph = (0 <= hpos - 1 && hpos - 1 < row->used[TEXT_AREA])
+                                                   ? row->glyphs[TEXT_AREA] + hpos - 1
+                                                   : NULL;
+                    // struct glyph *last_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
+                    bool skip_p = (previous_glyph != NULL
+                                   && previous_glyph->charpos == MATRIX_ROW_END_CHARPOS (row) - 1
+                                   && glyph->bytepos != essentials.zv_byte)
+                                    ? true
+                                  /* When a `buffer-display-table' entry contains
+                                  a visible tab character ("»"), the subsequent
+                                  STRETCH_GLYPH will have the same glyph->charpos
+                                  as the aforementioned visible tab character. */
+                                  : (previous_glyph != NULL
+                                     && previous_glyph->charpos == glyph->charpos)
+                                    ? true
+                                  : false;
+                    int posint = (row_position == POST_ZV)
+                                   ? -1
+                                 : (row_position == AT_ZV)
+                                    ? essentials.zv
+                                 : (glyph->bytepos != essentials.zv_byte
+                                    && glyph - row->glyphs[TEXT_AREA] == row->used[TEXT_AREA] - 1)
+                                   ? MATRIX_ROW_END_CHARPOS (row) - 1
+                                 : (glyph->bytepos == essentials.zv_byte
+                                    && glyph - row->glyphs[TEXT_AREA] == row->used[TEXT_AREA] - 1)
+                                   ? essentials.zv
+                                 : glyph->charpos;
+                    Lisp_Object specs = mc_assoc (make_fixnum (posint), BVAR (b, mc_conf));
+                    if (((header_line_format > 0 && vpos > 0)
+                         || header_line_format == 0)
+                        && !NILP (specs)
+                        && row->y <= window_text_bottom_y (w)
+                        && !skip_p
+                        && row_position != POST_ZV)
+                      {
+                        Lisp_Object lisp_type = mc_nth (1, specs);
+                        enum mc_cursor_type cursor_type = (CONSP (lisp_type))
+                                                          ? mc_lisp_to_cursor_type (XCAR (lisp_type))
+                                                          : mc_lisp_to_cursor_type (lisp_type);
+                        cursor_type = (glyph->type == IMAGE_GLYPH)
+                                      ? MC_HOLLOW_BOX
+                                      : cursor_type;
+                        int cursor_width = (CONSP (lisp_type))
+                                           ? XFIXNUM (XCAR (XCDR (lisp_type)))
+                                           : -1;
+                        Lisp_Object mc_foreground = mc_nth (2, specs);
+                        struct mc_RGB lsl_fg;
+                        if (STRINGP (mc_foreground))
+                          mc_xw_color_values (w, mc_foreground, &lsl_fg);
+                          else if (VECTORP (mc_foreground))
+                            {
+                              lsl_fg.red = XFLOAT_DATA (AREF (mc_foreground, 0));
+                              lsl_fg.green = XFLOAT_DATA (AREF (mc_foreground, 1));
+                              lsl_fg.blue = XFLOAT_DATA (AREF (mc_foreground, 2));
+                            }
+                            else if (NILP (mc_foreground))
+                              mc_color_picker (w, glyph, essentials, &lsl_fg,
+                                               posint, cursor_type, row_position,
+                                               MULTIPLE_CURSORS);
+                        int vpos = MATRIX_ROW_VPOS (row, matrix);
+                        int x_limit = window_box_width (w, TEXT_AREA);
+                        mc_engine (w, matrix, row, glyph, area, relative_x,
+                                   x_limit, row->y, glyph - row->glyphs[TEXT_AREA],
+                                   vpos, cursor_type, cursor_width, cursor_matrix,
+                                   essentials, row_position, lsl_fg,
+                                   MULTIPLE_CURSORS, draw_p, from_where, MC_CACHE);
+                      }
+                  }
+                if (!NILP (BVAR (b, fc_visible))
+                    && (essentials.active_p
+                        || (!essentials.active_p
+                            && !NILP (BVAR (b, fc_inactive_windows))))
+                    && essentials.fc_x <= text_area_width
+                    && essentials.fc_x >= w->mc.lnum_pixel_width)
+                  {
+                    int x_limit = window_box_width (w, TEXT_AREA);
+                    bool real_fake_cursor_p = (w->cursor.x == essentials.fc_x
+                                               && w->cursor.y == row->y
+                                               && w->cursor.hpos == glyph - row->glyphs[TEXT_AREA]
+                                               && w->cursor.vpos == vpos);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    struct mc_RGB lsl_fg;
+                    mc_color_picker (w, glyph, essentials, &lsl_fg, -1, MC_BAR,
+                                     row_position, FILL_COLUMN);
+                    if (hpos >= hpos_start
+                        && hpos < hpos_start + hpos_length
+                        && relative_x + glyph->pixel_width <= text_area_width
+                        && ((header_line_format > 0 && vpos > 0)
+                            || header_line_format == 0)
+                        && ((glyph != glyph_end - 1
+                             && essentials.fc_x >= relative_x
+                             && essentials.fc_x < relative_x + glyph->pixel_width)
+                            || (glyph == glyph_end - 1
+                                && essentials.fc_x >= relative_x))
+                        && row->y <= window_text_bottom_y (w)
+                        && !real_fake_cursor_p)
+                      mc_engine (w, matrix, row, glyph, area, relative_x, x_limit,
+                                 row->y, hpos, vpos, MC_BAR, 1, cursor_matrix,
+                                 essentials, row_position, lsl_fg, FILL_COLUMN,
+                                 draw_p, from_where, FC_CACHE);
+                  }
+                if (!NILP (BVAR (b, crosshairs))
+                    && !NILP (BVAR (b, ch_horizontal_ruler))
+                    && (essentials.active_p
+                        || (!essentials.active_p
+                            && !NILP (BVAR (b, ch_inactive_windows))))
+                    && vpos == w->cursor.vpos)
+                  {
+                    int x_limit = window_box_width (w, TEXT_AREA);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    struct mc_RGB lsl_fg;
+                    mc_color_picker (w, glyph, essentials, &lsl_fg, -1, MC_HBAR,
+                                     row_position, HORIZONTAL_RULER);
+                    /* Preserve support for default behavior such that a user may
+                    specify the height of an MC_HBAR, which begins its journey
+                    as the `cursor_width'.  `mc_get_cursor_geometry' readjusts. */
+                    if (hpos >= hpos_start
+                        && hpos < hpos_start + hpos_length)
+                      mc_engine (w, matrix, row, glyph, area, relative_x, x_limit,
+                                 row->y, hpos, vpos, MC_HBAR, 1, cursor_matrix,
+                                 essentials, row_position, lsl_fg, HORIZONTAL_RULER,
+                                 draw_p, from_where, CH_CACHE);
+                  }
+                if (!NILP (BVAR (b, crosshairs))
+                    && !NILP (BVAR (b, ch_vertical_ruler))
+                    && (essentials.active_p
+                        || (!essentials.active_p
+                            && !NILP (BVAR (b, ch_inactive_windows))))
+                    && !fill_column_trumps_p)
+                  {
+                    cursor_type = (glyph->type == IMAGE_GLYPH)
+                                  ? MC_HOLLOW_BOX
+                                  : MC_BAR;
+                    int x_limit = window_box_width (w, TEXT_AREA);
+                    bool real_fake_cursor_p = (w->cursor.y == row->y
+                                               && w->cursor.vpos == vpos);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    struct mc_RGB lsl_fg;
+                    mc_color_picker (w, glyph, essentials, &lsl_fg, -1, cursor_type,
+                                     row_position, VERTICAL_RULER);
+                    if (hpos >= hpos_start
+                        && hpos < hpos_start + hpos_length
+                        && ((header_line_format > 0 && vpos > 0)
+                            || header_line_format == 0)
+                        && ((glyph != glyph_end - 1
+                             && w->cursor.x >= relative_x
+                             && w->cursor.x < relative_x + glyph->pixel_width)
+                            || (glyph == glyph_end - 1
+                                && w->cursor.x >= relative_x))
+                        && row->y <= window_text_bottom_y (w)
+                        && !real_fake_cursor_p)
+                      mc_engine (w, matrix, row, glyph, area, relative_x, x_limit,
+                                 row->y, hpos, vpos, cursor_type, 1, cursor_matrix,
+                                 essentials, row_position, lsl_fg, VERTICAL_RULER,
+                                 draw_p, from_where, CH_CACHE);
+                  }
+                relative_x += glyph->pixel_width;
+              }
+          }
+      }
+  //  clock_t clock_end = clock();
+  //  double cpu_time_used = ((double) (clock_end - clock_start)) / CLOCKS_PER_SEC;
+  //  fprintf (stderr, "mc_draw_row (%s):  TIME (%f)\n", mc_window (w), cpu_time_used);
+}
+
+bool
+mc_redraw_row (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+               enum glyph_row_area area, int start_x, int start_hpos, int end_hpos,
+               bool clear_eol_p, enum draw_glyphs_face hl,
+               enum mc_redraw_row_type from_where)
+{
+  bool go_p = ((w->mc_matrix.cursors_used[MC_CACHE] > 0
+                || w->mc_matrix.cursors_used[CH_CACHE] > 0
+                || w->mc_matrix.cursors_used[FC_CACHE] > 0)
+               && area == TEXT_AREA
+               && row->used[area]);
+  if (!go_p)
+    return false;
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  int vpos = MATRIX_ROW_VPOS (row, matrix);
+  TRACE ((stderr, "mc_redraw_row (%d):  %s\n\
+  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+  vpos, mc_redraw_row_type_to_string (from_where), start_x, start_hpos, end_hpos));
+  struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+  enum mc_flavor glyph_flavor = NO_FLAVOR;
+  enum mc_cursor_type cursor_type = MC_NO_CURSOR;
+  int wd = -1;
+  bool active_p = (w == XWINDOW (f->selected_window)
+                   && f == FRAME_DISPLAY_INFO (f)->x_highlight_frame);
+  bool cursor_gc_p = false;
+  int overlaps = 0;
+  int x = 0;
+  bool draw_p = true;
+  //  clock_t clock_start = clock();
+  if (end_hpos > start_hpos)
+    x = mc_draw_glyphs (w, matrix, row, start_x, TEXT_AREA, start_hpos, end_hpos,
+                        hl, overlaps, vpos, lsl, glyph_flavor, cursor_type, wd,
+                        active_p, cursor_gc_p, MC_DRAW_GLYPH_STRING, draw_p);
+  //  clock_t clock_end = clock();
+  //  double time_glyphs = ((double) (clock_end - clock_start)) / CLOCKS_PER_SEC;
+  /* `redraw_overlapped_rows' calls `rif->clear_end_of_line'. */
+  if (clear_eol_p
+      && end_hpos > start_hpos)
+    {
+      /* Advance the output cursor. */
+      w->output_cursor.hpos = end_hpos;
+      w->output_cursor.x = x;
+      FRAME_RIF (f)->clear_end_of_line (w, row, TEXT_AREA, -1);
+    }
+  //  clock_start = clock();
+  int vnth = MATRIX_ROW_VPOS (row, matrix);
+  /* STRETCH_GLYPH may contain more than one fake cursor at the same HPOS. */
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    {
+      for (int nth = 0;
+           mc_traverse_cache_p (w->mc_matrix, cache_type, vnth, nth);
+           ++nth)
+        {
+          int x = w->mc_matrix.vpos[vnth].cache[cache_type][nth].x;
+          int fx = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fx;
+          int y = w->mc_matrix.vpos[vnth].cache[cache_type][nth].y;
+          int fy = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fy;
+          int hpos = w->mc_matrix.vpos[vnth].cache[cache_type][nth].hpos;
+          int vpos = w->mc_matrix.vpos[vnth].cache[cache_type][nth].vpos;
+          int wd = w->mc_matrix.vpos[vnth].cache[cache_type][nth].wd;
+          int h = w->mc_matrix.vpos[vnth].cache[cache_type][nth].h;
+          enum mc_cursor_type cursor_type = w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_type;
+          int cursor_width = w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_width;
+          struct mc_RGB lsl_fg = {.red = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.red,
+                                  .green = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.green,
+                                  .blue = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.blue};
+          //  struct mc_RGB lsl_bg = {.red = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.red,
+          //                          .green = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.green,
+          //                          .blue = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.blue};
+          bool active_p = w->mc_matrix.vpos[vnth].cache[cache_type][nth].active_p;
+          enum mc_flavor glyph_flavor = w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph_flavor;
+          bool enabled_p = w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p;
+          if (vpos == vnth
+              && ((hpos >= start_hpos
+                   && hpos < end_hpos)
+                  /* A floating cursor beyond the end of the glyph row. */
+                  || (hpos + 1 == start_hpos
+                      && hpos + 1 == end_hpos))
+              && enabled_p)
+            {
+              bool remove_p = false;
+              mc_draw_erase_hybrid (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h,
+                                    cursor_type, cursor_width, lsl_fg, active_p,
+                                    glyph_flavor, remove_p);
+            }
+        }
+    }
+  return true;
+  //  clock_end = clock();
+  //  double time_cursors = ((double) (clock_end - clock_start)) / CLOCKS_PER_SEC;
+  //  fprintf (stderr, "mc_redraw_row (%d):  hpos (%d/%d) | glyphs (%f) | cursors (%f)\n",
+  //                   vpos, start_hpos, end_hpos, time_glyphs, time_cursors);
+}
+
+void
+mc_erase_row (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row)
+{
+  int vnth = MATRIX_ROW_VPOS (row, matrix);
+  if (trace_redisplay_p)
+    fprintf (stderr, "mc_erase_row (%s):  vpos (%d)\n", mc_window (w), vnth);
+  //  if (trace_redisplay_p)
+  //    fprintf (stderr, "mc_erase_helper (%s):  cache (%s) | vpos (%d)\n",
+  //      mc_window (w), mc_cache_type_to_string (cache_type), vnth);
+  for (enum mc_cache_type cache_type = MC_CACHE;
+       cache_type < NO_CACHE;
+       ++cache_type)
+    {
+      for (int nth = 0;
+           mc_traverse_cache_p (w->mc_matrix, cache_type, vnth, nth);
+           ++nth)
+        {
+          int x = w->mc_matrix.vpos[vnth].cache[cache_type][nth].x;
+          int fx = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fx;
+          int y = w->mc_matrix.vpos[vnth].cache[cache_type][nth].y;
+          int fy = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fy;
+          int hpos = w->mc_matrix.vpos[vnth].cache[cache_type][nth].hpos;
+          int vpos = w->mc_matrix.vpos[vnth].cache[cache_type][nth].vpos;
+          int wd = w->mc_matrix.vpos[vnth].cache[cache_type][nth].wd;
+          int h = w->mc_matrix.vpos[vnth].cache[cache_type][nth].h;
+          enum mc_cursor_type cursor_type = w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_type;
+          int cursor_width = w->mc_matrix.vpos[vnth].cache[cache_type][nth].cursor_width;
+          //  struct mc_RGB lsl_fg = {.red = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.red,
+          //                          .green = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.green,
+          //                          .blue = w->mc_matrix.vpos[vnth].cache[cache_type][nth].fg.blue};
+          struct mc_RGB lsl_bg = {.red = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.red,
+                                  .green = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.green,
+                                  .blue = w->mc_matrix.vpos[vnth].cache[cache_type][nth].bg.blue};
+          bool active_p = w->mc_matrix.vpos[vnth].cache[cache_type][nth].active_p;
+          enum mc_flavor glyph_flavor = w->mc_matrix.vpos[vnth].cache[cache_type][nth].glyph_flavor;
+          bool enabled_p = w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p;
+          /* `matrix_row' in `dispnew.c` contains the following tests,
+          eassert (matrix && matrix->rows);
+          eassert (row >= 0 && row < matrix->nrows); */
+          bool barf_crash_one = (matrix && matrix->rows) ? false : true;
+          if (barf_crash_one)
+            continue;
+          bool barf_crash_two = (vpos >= 0 && vpos < matrix->nrows) ? false : true;
+          if (barf_crash_two)
+            continue;
+          if (vpos == vnth
+              && glyph_flavor == MC_GLYPH
+              && enabled_p)
+            {
+              mc_erase_cursor (w, matrix, row, x, y, hpos, vpos, glyph_flavor, cursor_type, wd);
+              w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p = false;
+              --w->mc_matrix.cursors_used[cache_type];
+            }
+            else if (vpos == vnth
+                     && enabled_p)
+              {
+                bool remove_p = true;
+                mc_draw_erase_hybrid (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h,
+                                      cursor_type, cursor_width, lsl_bg, active_p,
+                                      glyph_flavor, remove_p);
+                w->mc_matrix.vpos[vnth].cache[cache_type][nth].enabled_p = false;
+                --w->mc_matrix.cursors_used[cache_type];
+              }
+        }
+      w->mc_matrix.vpos[vnth].cache_used[cache_type] = 0;
+    }
+}
+
+/* Erase fake cursors from (min, run.current_y, run.desired_y) to end of window.
+  TRY_WINDOW_REUSING_CURRENT_MATRIX_DOWN:
+    run.height = it.last_visible_y - run.desired_y
+    [emacs -q:  Hold up-arrow key triggering auto-recenter at scroll-margin.]
+  TRY_WINDOW_REUSING_CURRENT_MATRIX_UP:
+    run.height = it.last_visible_y - run.current_y;
+    [emacs -q:  Hold up-arrow key triggering auto-recenter at scroll-margin.]
+  TRY_WINDOW_ID:
+    run.height = it.last_visible_y - max (run.current_y, run.desired_y)
+    [Add or remove lines from the buffer; e.g., RET or DEL.]
+  +-------------+ <= it.current_y == 0
+  |             |
+  |             | <= run.desired_y == 270 [up (↑)] == run.current_y < run.desired_y
+  |             |    run.height = it.last_visible_y - run.current_y;
+  |             |    run.height == 1080 - 540 == 540
+  |             |    [The entire bottom rectangle gets copied to upper run.desired_y.]
+  |             |
+  +-------------+ <= run.current_y == 540
+  |             |
+  |             | <= run.desired_y == 810 [down (↓)] == run.current_y > run.desired_y
+  |             |    run.height = it.last_visible_y - run.desired_y
+  |             |    run.height == 1080 - 810 == 270
+  |             |    [Top part of the lower rectangle gets copied to lower run.desired_y.]
+  |             |
+  +-------------+ <= it.last_visible_y == 1080 */
+void
+mc_pre_scroll_clean (struct window *w, struct run run, int start_vpos,
+                     int nrows_scrolled, enum mc_pre_scroll_clean_type from_where)
+{
+  if (MINI_WINDOW_P (w))
+    return;
+  bool go_one_p = (w->mc_matrix.cursors_used[MC_CACHE] > 0
+                   || w->mc_matrix.cursors_used[CH_CACHE] > 0
+                   || w->mc_matrix.cursors_used[FC_CACHE] > 0);
+  bool go_two_p = (BUFFERP (w->contents)
+                   && (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                       || !NILP (BVAR (XBUFFER (w->contents), fc_visible))
+                       || !NILP (BVAR (XBUFFER (w->contents), mc_conf))));
+  if (trace_redisplay_p)
+    fprintf (stderr, "mc_pre_scroll_clean (%s):\n\
+  %s | go_one_p (%s) | go_two_p (%s)\n\
+  start_vpos (%d) | nrows_scrolled (%d)\n\
+  %s:  run.current/desired_y (%d/%d) | run.height (%d)\n",
+    mc_window (w), (from_where == TRY_WINDOW_REUSING_CURRENT_MATRIX_DOWN)
+                     ? "TRY_WINDOW_REUSING_CURRENT_MATRIX_DOWN"
+                   : (from_where == TRY_WINDOW_REUSING_CURRENT_MATRIX_UP)
+                     ? "TRY_WINDOW_REUSING_CURRENT_MATRIX_UP"
+                   : (from_where == TRY_WINDOW_ID)
+                     ? "TRY_WINDOW_ID"
+                   : "UNKNOWN",
+    go_one_p ? "yes" : "no", go_two_p ? "yes" : "no",
+    start_vpos, nrows_scrolled,
+    run.current_y < run.desired_y ? "↓" : "↑",
+    run.current_y, run.desired_y, run.height);
+  if (!go_one_p && !go_two_p)
+    return;
+  bool updating_frame_p = false;
+  struct frame *f = XFRAME (w->frame);
+  if (XFRAME (w->frame) != f->mc_updating_frame
+      && (go_one_p || go_two_p))
+    {
+      updating_frame_p = true;
+      update_begin (f);
+    }
+  if (w->phys_cursor_on_p
+      && go_two_p)
+    erase_phys_cursor (w);
+  struct glyph_matrix *matrix = w->current_matrix;
+  for (int vnth = start_vpos;
+       matrix != NULL
+       && vnth < matrix->nrows
+       && MATRIX_ROW (matrix, vnth)->enabled_p
+       && go_one_p;
+       ++vnth)
+    {
+      struct glyph_row *row = MATRIX_ROW (matrix, vnth);
+      mc_erase_row (w, matrix, row);
+    }
+  if (updating_frame_p)
+    update_end (f);
+  // mc_reset_cache (w);
+}
+
+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)
+{
+  if (NILP (arg))
+    mc_stderr_p = !mc_stderr_p;
+  else
+    {
+      arg = Fprefix_numeric_value (arg);
+      mc_stderr_p = XFIXNUM (arg) > 0;
+    }
+  return Qnil;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 
 /***********************************************************************
 		      Window display dimensions
@@ -13395,6 +18036,69 @@ hscroll_window_tree (Lisp_Object window)
 	      else
 		pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+/* (gdb) bt
+#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:359
+#1  0x00000001001ee996 in die (
+    msg=0x10032fc88 "charpos < 0 || (charpos >= BUF_BEG (current_buffer) && charpos <= ZV)", file=0x10032e32d "xdisp.c", line=7951) at alloc.c:7214
+#2  0x000000010004d2ab in init_iterator (it=0x7fff5fbf9e80, w=0x11ae62150,
+    charpos=743, bytepos=743, row=0x0, base_face_id=DEFAULT_FACE_ID)
+    at xdisp.c:7950
+#3  0x000000010004efc9 in init_from_display_pos (it=0x7fff5fbf9e80,
+    w=0x11ae62150, pos=0x11f9c0250) at xdisp.c:8404
+#4  0x000000010004f546 in init_to_row_start (it=0x7fff5fbf9e80, w=0x11ae62150,
+    row=0x11f9c0200) at xdisp.c:8528
+#5  0x000000010006e536 in hscroll_window_tree (window=...) at xdisp.c:18619
+*/
+
+/* (gdb) bt
+#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:359
+#1  0x00000001001ecbc6 in die (
+    msg=0x10032fad8 "CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV",
+    file=0x10032c49d "xdisp.c", line=11746) at alloc.c:7214
+#2  0x000000010005885d in reseat_1 (it=0x7fff5fbf9e30, pos=...,
+    set_stop_p=false) at xdisp.c:11746
+#3  0x0000000100058707 in reseat (it=0x7fff5fbf9e30, pos=..., force_p=true)
+    at xdisp.c:11698
+#4  0x000000010004c732 in init_iterator (it=0x7fff5fbf9e30, w=0x11bf72c98,
+    charpos=114549, bytepos=114549, row=0x0, base_face_id=DEFAULT_FACE_ID)
+    at xdisp.c:8143
+#5  0x000000010004ce01 in init_from_display_pos (it=0x7fff5fbf9e30,
+    w=0x11bf72c98, pos=0x121243d50) at xdisp.c:8299
+#6  0x000000010004d37e in init_to_row_start (it=0x7fff5fbf9e30, w=0x11bf72c98,
+    row=0x121243d00) at xdisp.c:8423
+#7  0x000000010006c3f7 in hscroll_window_tree (window=...) at xdisp.c:18546
+*/
+
+  /* `init_iterator':  eassert (charpos < 0
+                                || (charpos >= BUF_BEG (current_buffer)
+                                    && charpos <= ZV)); */
+
+  struct display_pos *pos = &cursor_row->start;
+  ptrdiff_t charpos = CHARPOS (pos->pos);
+
+  bool barf_crash_one = (charpos < 0
+                         || (charpos >= BUF_BEG (current_buffer)
+                             && charpos <= ZV))
+                        ? false
+                        : true;
+  if (barf_crash_one)
+    return hscrolled_p;
+
+  /* `reseat_1':  CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV */
+  bool barf_crash_two = (charpos >= BEGV && charpos <= ZV)
+                         ? false
+                         : true;
+  if (barf_crash_two)
+    return hscrolled_p;
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 	      /* Move iterator to pt starting at cursor_row->start in
 		 a line with infinite width.  */
 	      init_to_row_start (&it, w, cursor_row);
@@ -14287,9 +18991,22 @@ redisplay_internal (void)
 	      *w->desired_matrix->method = 0;
 	      debug_method_add (w, "optimization 1");
 #endif
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
 #ifdef HAVE_WINDOW_SYSTEM
+  if (BUFFERP (w->contents)
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+    mc_update_window_fringes (w, false);
+    else
 	      update_window_fringes (w, false);
 #endif
+
+/* *************************************************************************** */
+
+
 	      goto update;
 	    }
 	  else
@@ -17687,10 +22404,22 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
     }
 
 #ifdef HAVE_WINDOW_SYSTEM
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  bool keep_current_p = (just_this_one_p
+                         || (!used_current_matrix_p && !overlay_arrow_seen)
+                         || w->pseudo_window_p);
+
+  bool fringes_updated_p = (BUFFERP (w->contents)
+                            && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+                           ? mc_update_window_fringes (w, keep_current_p)
+                           : update_window_fringes (w, keep_current_p);
+
   if (FRAME_WINDOW_P (f)
-      && update_window_fringes (w, (just_this_one_p
-				    || (!used_current_matrix_p && !overlay_arrow_seen)
-				    || w->pseudo_window_p)))
+      && fringes_updated_p)
     {
       update_begin (f);
       block_input ();
@@ -17705,6 +22434,9 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
       update_end (f);
     }
 
+/* *************************************************************************** */
+
+
   if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
     x_draw_bottom_divider (w);
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -18010,6 +22742,7 @@ try_window_reusing_current_matrix (struct window *w)
 	     scroll_run_hook will clear the cursor, and use the
 	     current matrix to get the height of the row the cursor is
 	     in.  */
+
 	  run.current_y = start_row->y;
 	  run.desired_y = it.current_y;
 	  run.height = it.last_visible_y - it.current_y;
@@ -18019,6 +22752,16 @@ try_window_reusing_current_matrix (struct window *w)
 	      update_begin (f);
 	      FRAME_RIF (f)->update_window_begin_hook (w);
 	      FRAME_RIF (f)->clear_window_mouse_face (w);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    mc_pre_scroll_clean (w, run, start_vpos, nrows_scrolled, TRY_WINDOW_REUSING_CURRENT_MATRIX_DOWN);
+
+/* *************************************************************************** */
+
+
 	      FRAME_RIF (f)->scroll_run_hook (w, &run);
 	      FRAME_RIF (f)->update_window_end_hook (w, false, false);
 	      update_end (f);
@@ -18173,6 +22916,7 @@ try_window_reusing_current_matrix (struct window *w)
 	}
 
       /* Scroll the display.  */
+
       run.current_y = first_reusable_row->y;
       run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
       run.height = it.last_visible_y - run.current_y;
@@ -18183,6 +22927,16 @@ try_window_reusing_current_matrix (struct window *w)
 	  update_begin (f);
 	  FRAME_RIF (f)->update_window_begin_hook (w);
 	  FRAME_RIF (f)->clear_window_mouse_face (w);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    mc_pre_scroll_clean (w, run, start_vpos, nrows_scrolled, TRY_WINDOW_REUSING_CURRENT_MATRIX_UP);
+
+/* *************************************************************************** */
+
+
 	  FRAME_RIF (f)->scroll_run_hook (w, &run);
 	  FRAME_RIF (f)->update_window_end_hook (w, false, false);
 	  update_end (f);
@@ -19127,6 +23881,7 @@ try_window_id (struct window *w)
   /* Scroll the display.  Do it before changing the current matrix so
      that xterm.c doesn't get confused about where the cursor glyph is
      found.  */
+
   if (dy && run.height)
     {
       update_begin (f);
@@ -19135,6 +23890,16 @@ try_window_id (struct window *w)
 	{
 	  FRAME_RIF (f)->update_window_begin_hook (w);
 	  FRAME_RIF (f)->clear_window_mouse_face (w);
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    mc_pre_scroll_clean (w, run, first_unchanged_at_end_vpos, dvpos, TRY_WINDOW_ID);
+
+/* *************************************************************************** */
+
+
 	  FRAME_RIF (f)->scroll_run_hook (w, &run);
 	  FRAME_RIF (f)->update_window_end_hook (w, false, false);
 	}
@@ -21273,6 +26038,17 @@ maybe_produce_line_number (struct it *it)
       SET_TEXT_POS (tem_it.position, -1, -1);
       PRODUCE_GLYPHS (&tem_it);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      /* This permits us to inspect the HPOS of line number glyphs and the space
+      padding before/after the line numbers.  We set `glyph->hpos` elsewhere. */
+      tem_it.hpos += 1;
+
+/* *************************************************************************** */
+
+
       /* Stop producing glyphs, and refrain from producing the line
 	 number, if we don't have enough space on this line.  */
       if (tem_it.current_x >= width_limit)
@@ -21284,6 +26060,30 @@ maybe_produce_line_number (struct it *it)
 	}
     }
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  Lisp_Object buf = it->w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  struct buffer *old_buffer = NULL;
+  /* Needed so that buffer-local values can be determined; e.g., when switching
+  to the minibuffer. */
+  if (b != current_buffer)
+    {
+      old_buffer = current_buffer;
+      set_buffer_internal (b);
+    }
+  it->w->mc.lnum_pixel_width = (!NILP (Vdisplay_line_numbers))
+                               ? tem_it.current_x
+                               : 0;
+  if (old_buffer)
+    set_buffer_internal (old_buffer);
+
+/* *************************************************************************** */
+
+
   /* Record the width in pixels we need for the line number display.  */
   it->lnum_pixel_width = tem_it.current_x;
   /* Copy the produced glyphs into IT's glyph_row.  */
@@ -27092,6 +31892,17 @@ append_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       if (it->pixel_width > 0)
@@ -27175,6 +31986,17 @@ append_composite_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[it->area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
       glyph->charpos = it->cmp_it.charpos;
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -27383,6 +32205,17 @@ produce_image_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27486,6 +32319,17 @@ produce_xwidget_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27572,6 +32416,17 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
 	    width -= it->first_visible_x - it->current_x;
 	  eassert (width > 0);
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = object;
       /* FIXME: It would be better to use TYPE_MAX here, but
@@ -28026,6 +32881,17 @@ 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->hpos = it->hpos;
+      glyph->bytepos = IT_BYTEPOS (*it);
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -29076,10 +33942,20 @@ x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
 
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (!mc_redraw_row (w, w->current_matrix, row, updated_area, w->output_cursor.x,
+                      hpos, hpos + len, false, DRAW_NORMAL_TEXT, X_INSERT_GLYPHS))
   draw_glyphs (w, w->output_cursor.x, row, updated_area,
 	       hpos, hpos + len,
 	       DRAW_NORMAL_TEXT, 0);
 
+/* *************************************************************************** */
+
+
   /* Advance the output cursor.  */
   w->output_cursor.hpos += len;
   w->output_cursor.x += shift_by_width;
@@ -29505,9 +34381,19 @@ x_fix_overlapping_area (struct window *w, struct glyph_row *row,
 	  while (i < row->used[area]
 		 && row->glyphs[area][i].overlaps_vertically_p);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      if (!mc_redraw_row (w, w->current_matrix, row, area, start_x, start, i,
+          false, DRAW_NORMAL_TEXT, X_FIX_OVERLAPPING_AREA))
 	  draw_glyphs (w, start_x, row, area,
 		       start, i,
 		       DRAW_NORMAL_TEXT, overlaps);
+
+/* *************************************************************************** */
+
+
 	}
       else
 	{
@@ -29758,10 +34644,17 @@ display_and_set_cursor (struct window *w, bool on,
   new_cursor_type = get_window_cursor_type (w, glyph,
 					    &new_cursor_width, &active_cursor);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
   /* If cursor is currently being shown and we don't want it to be or
      it is in the wrong place, or the cursor type is not what we want,
      erase it.  */
   if (w->phys_cursor_on_p
+      && NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && NILP (BVAR (XBUFFER (w->contents), fc_visible))
+      && NILP (BVAR (XBUFFER (w->contents), mc_conf))
       && (!on
 	  || w->phys_cursor.x != x
 	  || w->phys_cursor.y != y
@@ -29774,6 +34667,9 @@ display_and_set_cursor (struct window *w, bool on,
 	      && new_cursor_width != w->phys_cursor_width)))
     erase_phys_cursor (w);
 
+/* *************************************************************************** */
+
+
   /* Don't check phys_cursor_on_p here because that flag is only set
      to false in some cases where we know that the cursor has been
      completely erased, to avoid the extra work of erasing the cursor
@@ -29792,9 +34688,19 @@ display_and_set_cursor (struct window *w, bool on,
       w->phys_cursor.vpos = vpos;
     }
 
-  FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
-                                     new_cursor_type, new_cursor_width,
-                                     on, active_cursor);
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && NILP (BVAR (XBUFFER (w->contents), fc_visible))
+      && NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+    FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y, new_cursor_type,
+                                       new_cursor_width, on, active_cursor);
+
+/* *************************************************************************** */
+
+
 }
 
 
@@ -29887,7 +34793,18 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (XFRAME (w->frame)))
     {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      if (!mc_redraw_row (w, w->current_matrix, row, TEXT_AREA, start_x,
+                          start_hpos, end_hpos, false, draw, DRAW_ROW_WITH_MOUSE_FACE))
       draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
+
+/* *************************************************************************** */
+
+
       return;
     }
 #endif
@@ -31945,11 +36862,23 @@ expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
   struct glyph *last;
   int first_x, start_x, x;
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
   if (area == TEXT_AREA && row->fill_line_p)
+    {
+      if (!mc_redraw_row (w, w->current_matrix, row, area, 0, 0, row->used[area],
+                          false, DRAW_NORMAL_TEXT, EXPOSE_AREA_ONE))
     /* If row extends face to end of line write the whole line.  */
     draw_glyphs (w, 0, row, area,
 		 0, row->used[area],
 		 DRAW_NORMAL_TEXT, 0);
+    }
+
+/* *************************************************************************** */
+
+
   else
     {
       /* Set START_X to the window-relative start position for drawing glyphs of
@@ -31981,11 +36910,23 @@ expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
 	  ++last;
 	}
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
       /* Repaint.  */
-      if (last > first)
+      /* Floating fake cursors will exist when (last == first). */
+      if (!mc_redraw_row (w, w->current_matrix, row, area, first_x - start_x,
+                          first - row->glyphs[area], last - row->glyphs[area],
+                          false, DRAW_NORMAL_TEXT, EXPOSE_AREA_TWO)
+          && last > first)
 	draw_glyphs (w, first_x - start_x, row, area,
 		     first - row->glyphs[area], last - row->glyphs[area],
 		     DRAW_NORMAL_TEXT, 0);
+
+/* *************************************************************************** */
+
+
     }
 }
 
@@ -31999,10 +36940,22 @@ expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
 {
   eassert (row->enabled_p);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
   if (row->mode_line_p || w->pseudo_window_p)
+    {
+      if (!mc_redraw_row (w, w->current_matrix, row, TEXT_AREA, 0, 0,
+                          row->used[TEXT_AREA], false, DRAW_NORMAL_TEXT, EXPOSE_LINE))
     draw_glyphs (w, 0, row, TEXT_AREA,
 		 0, row->used[TEXT_AREA],
 		 DRAW_NORMAL_TEXT, 0);
+    }
+
+/* *************************************************************************** */
+
+
   else
     {
       if (row->used[LEFT_MARGIN_AREA])
@@ -32550,6 +37503,22 @@ 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_current_column);
+
+  defsubr (&Smc_stderr);
+
+/* *************************************************************************** */
+
+
   Vwith_echo_area_save_vector = Qnil;
   staticpro (&Vwith_echo_area_save_vector);
 
diff --git a/src/xterm.c b/src/xterm.c
index 5aa3e3f..0e5d75b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -132,6 +132,885 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include <X11/XKBlib.h>
 #endif
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+#ifdef GLYPH_DEBUG
+static void x_check_font (struct frame *, struct font *);
+#endif
+
+static void x_set_mode_line_face_gc (struct glyph_string *);
+
+static void x_set_mouse_face_gc (struct glyph_string *);
+
+static void x_clip_to_row (struct window *, struct glyph_row *, enum glyph_row_area, GC);
+
+static void x_draw_rectangle (struct frame *, GC, int, int, int, int);
+
+static void x_reset_clip_rectangles (struct frame *, GC);
+
+static void x_fill_rectangle (struct frame *, GC, int, int, int, int);
+
+static void x_draw_glyph_string_bg_rect (struct glyph_string *, int, int, int, int);
+
+static void x_set_clip_rectangles (struct frame *, GC, XRectangle *, int);
+
+static void x_set_glyph_string_clipping (struct glyph_string *);
+
+static void x_draw_glyph_string_background (struct glyph_string *, bool);
+
+static void x_draw_glyph_string_box (struct glyph_string *);
+
+static void x_set_glyph_string_clipping_exactly (struct glyph_string *, struct glyph_string *);
+
+static void x_draw_image_glyph_string (struct glyph_string *);
+
+static void x_draw_glyph_string_foreground (struct glyph_string *);
+
+static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
+
+static void x_draw_glyphless_glyph_string_foreground (struct glyph_string *);
+
+static void x_draw_underwave (struct glyph_string *);
+
+void
+mc_xw_color_values (struct window *w, Lisp_Object color, struct mc_RGB *lsl)
+{
+  CHECK_STRING (color);
+  XColor temp;
+  struct frame *f = decode_window_system_frame (w->frame);
+  if (x_defined_color (f, SSDATA (color), &temp, false))
+    {
+      lsl->red = temp.red / 65535.0;
+      lsl->green = temp.green / 65535.0;
+      lsl->blue = temp.blue / 65535.0;
+    }
+  else
+    {
+      lsl->red = -1.0;
+      lsl->green = -1.0;
+      lsl->blue = -1.0;
+    }
+}
+
+/* Set S->gc to a suitable GC for drawing glyph string S in cursor face. */
+static void
+mc_x_set_cursor_gc (struct glyph_string *s, bool cursor_gc_p)
+{
+  if (cursor_gc_p)
+    {
+      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)
+      && !s->cmp)
+    s->gc = s->f->output_data.x->cursor_gc;
+  else
+    {
+      /* Cursor on non-default face: must merge. */
+      XGCValues xgcv;
+      unsigned long mask;
+      xgcv.background = s->f->output_data.x->cursor_pixel;
+      xgcv.foreground = s->face->background;
+      /* If the glyph would be invisible, try a different foreground. */
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->face->foreground;
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
+      if (xgcv.foreground == xgcv.background)
+        xgcv.foreground = s->face->foreground;
+      /* Make sure the cursor is distinct from text in this face. */
+      if (xgcv.background == s->face->background
+          && xgcv.foreground == s->face->foreground)
+        {
+          xgcv.background = s->face->foreground;
+          xgcv.foreground = s->face->background;
+        }
+      IF_DEBUG (x_check_font (s->f, s->font));
+      xgcv.graphics_exposures = False;
+      mask = GCForeground | GCBackground | GCGraphicsExposures;
+      if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
+        XChangeGC (s->display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
+                   mask, &xgcv);
+      else
+        FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
+          = XCreateGC (s->display, FRAME_X_WINDOW (s->f), mask, &xgcv);
+      s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
+    }
+}
+
+/* Set S->gc of glyph string S for drawing that glyph string.  Set
+   S->stippled_p to a non-zero value if the face of S has a stipple pattern. */
+static void
+mc_x_set_glyph_string_gc (struct glyph_string *s, bool cursor_gc_p)
+{
+  prepare_face_for_display (s->f, s->face);
+  if (s->hl == DRAW_NORMAL_TEXT)
+    {
+      s->gc = s->face->gc;
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_INVERSE_VIDEO)
+    {
+      x_set_mode_line_face_gc (s);
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_CURSOR)
+    {
+      mc_x_set_cursor_gc (s, cursor_gc_p);
+      s->stippled_p = false;
+    }
+  else if (s->hl == DRAW_MOUSE_FACE)
+    {
+      x_set_mouse_face_gc (s);
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else if (s->hl == DRAW_IMAGE_RAISED
+           || s->hl == DRAW_IMAGE_SUNKEN)
+    {
+      s->gc = s->face->gc;
+      s->stippled_p = s->face->stipple != 0;
+    }
+  else
+    emacs_abort ();
+  /* GC must have been set. */
+  eassert (s->gc != 0);
+}
+
+/* Draw a hollow box cursor on window W in glyph row ROW. */
+static void
+mc_x_draw_hollow_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                         int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+  Display *dpy = FRAME_X_DISPLAY (f);
+  XGCValues xgcv;
+  GC gc;
+  /* Get the glyph the cursor is on.  If we can't tell because
+     the current matrix is invalid or such, give up. */
+  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  if (cursor_glyph == NULL)
+    return;
+  /* The foreground of cursor_gc is typically the same as the normal
+     background color, which can cause the cursor box to be invisible. */
+  xgcv.foreground = f->output_data.x->cursor_pixel;
+  if (dpyinfo->scratch_cursor_gc)
+    XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv);
+  else
+    dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_X_WINDOW (f),
+              GCForeground, &xgcv);
+  gc = dpyinfo->scratch_cursor_gc;
+  /* Set clipping, draw the rectangle, and reset clipping again. */
+  x_clip_to_row (w, row, TEXT_AREA, gc);
+  /* `x_draw_rectangle' needs a WD and H that are 1 pixel less. */
+  int rx = fx;
+  int ry = fy;
+  int rw = wd - 1;
+  int rh = h - 1;
+  x_draw_rectangle (f, gc, rx, ry, rw, rh);
+/*
+  fprintf (stderr, "mc_x_draw_hollow_cursor:  rx (%d) | ry (%d) | rw (%d) | rh (%d)\n",
+                    rx, ry, rw, rh);
+*/
+  x_reset_clip_rectangles (f, gc);
+}
+
+/* Draw a bar cursor on window W in glyph row ROW. */
+static void
+mc_x_draw_bar_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                      int x, int fx, int y, int fy, int hpos, int vpos, int wd, int h,
+                      int width, enum mc_cursor_type kind, bool cursor_gc_invisible_okay_p)
+{
+  struct frame *f = XFRAME (w->frame);
+  /* If cursor is out of bounds, don't draw garbage.  This can happen
+     in mini-buffer windows when switching between echo area glyphs
+     and mini-buffer. */
+  struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+  if (cursor_glyph == NULL)
+    return;
+  /* Experimental avoidance of cursor on xwidget. */
+  if (cursor_glyph->type == XWIDGET_GLYPH)
+    return;
+  /* If on an image, draw like a normal cursor.  That's usually better
+     visible than drawing a bar, esp. if the image is large so that
+     the bar might not be in the window. */
+  if (cursor_glyph->type == IMAGE_GLYPH)
+    {
+      struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+      enum mc_flavor glyph_flavor = NO_FLAVOR;
+      enum mc_cursor_type cursor_type = MC_HOLLOW_BOX;
+      bool active_p = false;
+      bool cursor_gc_p = false;
+      mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                            glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+    }
+  else
+    {
+      Display *dpy = FRAME_X_DISPLAY (f);
+      Window window = FRAME_X_WINDOW (f);
+      GC gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
+      unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
+      struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+      XGCValues xgcv;
+      /* If the glyph's background equals the color we normally draw
+   the bars cursor in, the bar cursor in its normal color is
+   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
+          && !cursor_gc_invisible_okay_p)
+        xgcv.background = xgcv.foreground = face->foreground;
+      else
+        xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
+      xgcv.graphics_exposures = False;
+      if (gc)
+        XChangeGC (dpy, gc, mask, &xgcv);
+      else
+        {
+          gc = XCreateGC (dpy, window, mask, &xgcv);
+          FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
+        }
+      x_clip_to_row (w, row, TEXT_AREA, gc);
+      x_fill_rectangle (f, gc, fx, fy, wd, h);
+      x_reset_clip_rectangles (f, gc);
+    }
+}
+
+/* RIF: Draw cursor on window W. */
+static void
+mc_x_draw_window_cursor (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                         int x, int fx, int y, int fy, int hpos, int vpos, int wd,
+                         int h, struct mc_RGB lsl, enum mc_cursor_type cursor_type,
+                         int cursor_width, enum mc_flavor glyph_flavor, bool on_p,
+                         bool active_p)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  /* The fringe bitmaps are presently handled elsewhere, but could someday
+  be managed (in part) at this section of code. */
+  if (on_p)
+    {
+      if (row->exact_window_width_line_p
+          && (row->reversed_p
+              ? (hpos < 0)
+              : (hpos >= row->used[TEXT_AREA])))
+        {
+          row->cursor_in_fringe_p = true;
+          mc_draw_fringe_bitmap (w, row, row->reversed_p, cursor_type);
+        }
+      else
+        {
+  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 * */
+  XGCValues xgcv;
+  XGetGCValues (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, GCForeground, &xgcv);
+  XGetGCValues (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, GCBackground, &xgcv);
+  XColor color;
+  color.red = min (65535, 65535 * lsl.red);
+  color.green = min (65535, 65535 * lsl.green);
+  color.blue = min (65535, 65535 * lsl.blue);
+  /* `x_alloc_nearest_color' sets the `color.pixel`. */
+  x_alloc_nearest_color (f, cmap, &color);
+  switch (cursor_type)
+  {
+    case MC_NO_FRINGE_BITMAP:
+      break;
+    case MC_NO_CURSOR:
+      break;
+    case MC_RIGHT_FRINGE_BITMAP:
+      break;
+    case MC_LEFT_FRINGE_BITMAP:
+      break;
+    case MC_FRAMED_BOX:
+    {
+      struct glyph *cursor_glyph = mc_get_cursor_glyph (w, matrix, row, hpos, vpos);
+      if (cursor_glyph == NULL)
+        return;
+      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_beg = (region_active_p) ? mc_region_limit (1) : -1;
+      ptrdiff_t region_end = (region_active_p) ? mc_region_limit (0) : -1;
+      if (cursor_glyph->type != IMAGE_GLYPH && lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+          functionality of `x_make_gc' in xfns.c. */
+          if (region_active_p
+              && active_p
+              && cursor_glyph->charpos == region_beg)
+            {
+              enum face_id hollow_active_region_beg_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+              struct face *hollow_active_region_beg_face = FACE_FROM_ID (f, hollow_active_region_beg_face_id);
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+              XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_beg_face->foreground);
+            }
+            else if (region_active_p
+                     && active_p
+                     && cursor_glyph->charpos == region_end)
+              {
+                enum face_id hollow_active_region_end_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                struct face *hollow_active_region_end_face = FACE_FROM_ID (f, hollow_active_region_end_face_id);
+                enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_end_face->background);
+              }
+              else if (region_active_p
+                       && active_p
+                       && cursor_glyph->charpos > region_beg
+                       && cursor_glyph->charpos < region_end)
+                {
+                  enum face_id hollow_active_region_between_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+                  struct face *hollow_active_region_between_face = FACE_FROM_ID (f, hollow_active_region_between_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                  XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_between_face->foreground);
+                }
+                else if (active_p)
+                  {
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                    XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->background);
+                  }
+                  else if (!active_p)
+                    {
+                      enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-pre-zv-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, hollow_inactive_face->foreground);
+                      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_inactive_face->background);
+                    }
+          block_input ();
+          /* Force `mc_x_set_cursor_gc' to use `s->f->output_data.x->cursor_gc'. */
+          bool cursor_gc_p = true;
+          mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                                glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+          XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.foreground);
+          XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.background);
+          unblock_input ();
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'. */
+          f->output_data.x->cursor_pixel = color.pixel;
+          mc_x_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else if (cursor_glyph->type == IMAGE_GLYPH && lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+          {
+            /* Temporarily hijack `f->output_data.x->cursor_pixel'. */
+            f->output_data.x->cursor_pixel = color.pixel;
+            mc_x_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+            f->output_data.x->cursor_pixel = original_cursor_pixel;
+          }
+          else
+            {
+              /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+              functionality of `x_make_gc' in xfns.c. */
+              if (region_active_p
+                  && active_p
+                  && cursor_glyph->charpos == region_beg)
+                {
+                  enum face_id hollow_active_region_beg_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                  struct face *hollow_active_region_beg_face = FACE_FROM_ID (f, hollow_active_region_beg_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                  XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_beg_face->foreground);
+                }
+                else if (region_active_p
+                         && active_p
+                         && cursor_glyph->charpos == region_end)
+                  {
+                    enum face_id hollow_active_region_end_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-at-region-pre-zv-face"), true);
+                    struct face *hollow_active_region_end_face = FACE_FROM_ID (f, hollow_active_region_end_face_id);
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                    XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_end_face->background);
+                  }
+                  else if (region_active_p
+                           && active_p
+                           && cursor_glyph->charpos > region_beg
+                           && cursor_glyph->charpos < region_end)
+                    {
+                      enum face_id hollow_active_region_between_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-in-region-pre-zv-face"), true);
+                      struct face *hollow_active_region_between_face = FACE_FROM_ID (f, hollow_active_region_between_face_id);
+                      enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_between_face->foreground);
+                    }
+                    else if (active_p)
+                      {
+                        enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-pre-zv-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, hollow_active_face->foreground);
+                        XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->background);
+                      }
+                      else if (!active_p)
+                        {
+                          enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-pre-zv-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, hollow_inactive_face->foreground);
+                          XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_inactive_face->background);
+                        }
+              block_input ();
+              /* Force `mc_x_set_cursor_gc' to use `s->f->output_data.x->cursor_gc'. */
+              bool cursor_gc_p = true;
+              mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos,
+                                    lsl, glyph_flavor, cursor_type, wd, active_p,
+                                    cursor_gc_p);
+              XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.foreground);
+              XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.background);
+              unblock_input ();
+              /* Draw the frame around the box. */
+              mc_x_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+            }
+      break;
+    }
+    case MC_HOLLOW_BOX:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'. */
+          f->output_data.x->cursor_pixel = color.pixel;
+          mc_x_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          mc_x_draw_hollow_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h);
+      break;
+    }
+    case MC_FILLED_BOX:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        /* Temporarily hijack `f->output_data.x->cursor_gc' by borrowing the
+        functionality of `x_make_gc' in xfns.c. */
+        {
+          block_input ();
+          XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, FRAME_BACKGROUND_PIXEL (f));
+          XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, color.pixel);
+          /* Force `mc_x_set_cursor_gc' to use `s->f->output_data.x->cursor_gc'. */
+          bool cursor_gc_p = true;
+          mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                                glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+          XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.foreground);
+          XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, xgcv.background);
+          unblock_input ();
+        }
+        else
+          {
+            bool cursor_gc_p = false;
+            mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                                  glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+          }
+      break;
+    }
+    case MC_BAR:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'. */
+          f->output_data.x->cursor_pixel = color.pixel;
+          bool cursor_gc_invisible_okay_p = true;
+          mc_x_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h,
+                                cursor_width, MC_BAR, cursor_gc_invisible_okay_p);
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          {
+            bool cursor_gc_invisible_okay_p = false;
+            mc_x_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                  h, cursor_width, MC_BAR, cursor_gc_invisible_okay_p);
+          }
+      break;
+    }
+    case MC_HBAR:
+    {
+      if (lsl.red >= 0 && lsl.green >= 0 && lsl.blue >= 0)
+        {
+          /* Temporarily hijack `f->output_data.x->cursor_pixel'. */
+          f->output_data.x->cursor_pixel = color.pixel;
+          bool cursor_gc_invisible_okay_p = true;
+          mc_x_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd, h,
+                                cursor_width, MC_HBAR, cursor_gc_invisible_okay_p);
+          f->output_data.x->cursor_pixel = original_cursor_pixel;
+        }
+        else
+          {
+            bool cursor_gc_invisible_okay_p = false;
+            mc_x_draw_bar_cursor (w, matrix, row, x, fx, y, fy, hpos, vpos, wd,
+                                  h, cursor_width, MC_HBAR, cursor_gc_invisible_okay_p);
+          }
+      break;
+    }
+    default:
+      emacs_abort ();
+  }
+        }
+#ifdef HAVE_X_I18N
+  if (w == XWINDOW (f->selected_window))
+    if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMPreeditPosition))
+      xic_set_preeditarea (w, x, y);
+#endif
+    }
+  XFlush (FRAME_X_DISPLAY (f));
+}
+
+/* Draw stretch glyph string S. */
+static void
+mc_x_draw_stretch_glyph_string (struct glyph_string *s)
+{
+  eassert (s->first_glyph->type == STRETCH_GLYPH);
+  if (s->hl == DRAW_CURSOR
+      && !x_stretch_cursor_p)
+    {
+      /* If `x-stretch-cursor' is nil, don't draw a block cursor as wide as the
+      stretch glyph. */
+      int width, background_width = s->background_width;
+      int x = s->x;
+      if (!s->row->reversed_p)
+        {
+          int left_x = window_box_left_offset (s->w, TEXT_AREA);
+          if (x < left_x)
+            {
+              background_width -= left_x - x;
+              x = left_x;
+            }
+        }
+        else
+          {
+            /* In R2L rows, draw the cursor on the right edge of the
+               stretch glyph. */
+            int right_x = window_box_right (s->w, TEXT_AREA);
+            if (x + background_width > right_x)
+              background_width -= x - right_x;
+            x += background_width;
+          }
+      width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+      if (s->row->reversed_p)
+        x -= width;
+      /* Draw cursor. */
+      x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
+      /* Clear rest using the GC of the original non-cursor face. */
+      if (width < background_width)
+        {
+          int y = s->y;
+          int w = background_width - width, h = s->height;
+          XRectangle r;
+          GC gc;
+          if (!s->row->reversed_p)
+            x += width;
+          else
+            x = s->x;
+          if (s->row->mouse_face_p
+              && cursor_in_mouse_face_p (s->w))
+            {
+              x_set_mouse_face_gc (s);
+              gc = s->gc;
+            }
+          else
+            gc = s->face->gc;
+          get_glyph_string_clip_rect (s, &r);
+          x_set_clip_rectangles (s->f, gc, &r, 1);
+          if (s->face->stipple)
+            {
+              /* Fill background with a stipple pattern. */
+              XSetFillStyle (s->display, gc, FillOpaqueStippled);
+              x_fill_rectangle (s->f, gc, x, y, w, h);
+              XSetFillStyle (s->display, gc, FillSolid);
+            }
+          else
+            {
+              XGCValues xgcv;
+              XGetGCValues (s->display, gc, GCForeground | GCBackground, &xgcv);
+              XSetForeground (s->display, gc, xgcv.background);
+              x_fill_rectangle (s->f, gc, x, y, w, h);
+              XSetForeground (s->display, gc, xgcv.foreground);
+            }
+          x_reset_clip_rectangles (s->f, gc);
+        }
+    }
+  else if (!s->background_filled_p)
+    {
+      int background_width = s->background_width;
+      int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+      /* Don't draw into left margin, fringe or scrollbar area
+         except for header line and mode line. */
+      if (x < left_x && !s->row->mode_line_p)
+        {
+          background_width -= left_x - x;
+          x = left_x;
+        }
+      if (background_width > 0)
+        x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+    }
+  s->background_filled_p = true;
+}
+
+/* Draw glyph string S. */
+static void
+mc_x_draw_glyph_string (struct glyph_string *s, struct glyph_matrix *matrix, struct glyph_row *row,
+                        struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+                        enum mc_cursor_type cursor_type, int cursor_width,
+                        bool active_p, bool cursor_gc_p)
+{
+  bool relief_drawn_p = false;
+  /* If S draws into the background of its successors, draw the
+     background of the successors first so that S can draw into it.
+     This makes S->next use XDrawString instead of XDrawImageString. */
+  if (s->next && s->right_overhang && !s->for_overlaps)
+    {
+      int width;
+      struct glyph_string *next;
+      for (width = 0, next = s->next;
+           next && width < s->right_overhang;
+           width += next->width, next = next->next)
+        if (next->first_glyph->type != IMAGE_GLYPH)
+          {
+            mc_x_set_glyph_string_gc (next, cursor_gc_p);
+            x_set_glyph_string_clipping (next);
+            if (next->first_glyph->type == STRETCH_GLYPH)
+              mc_x_draw_stretch_glyph_string (next);
+            else
+              x_draw_glyph_string_background (next, true);
+            next->num_clips = 0;
+          }
+    }
+  /* Set up S->gc, set clipping and draw S. */
+  mc_x_set_glyph_string_gc (s, cursor_gc_p);
+  /* Draw relief (if any) in advance for char/composition so that the
+     glyph string can be drawn over it. */
+  if (!s->for_overlaps
+      && s->face->box != FACE_NO_BOX
+      && (s->first_glyph->type == CHAR_GLYPH
+          || s->first_glyph->type == COMPOSITE_GLYPH))
+    {
+      x_set_glyph_string_clipping (s);
+      x_draw_glyph_string_background (s, true);
+      x_draw_glyph_string_box (s);
+      x_set_glyph_string_clipping (s);
+      relief_drawn_p = true;
+    }
+    else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
+             && !s->clip_tail
+             && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+                 || (s->next && s->next->hl != s->hl && s->right_overhang)))
+      /* We must clip just this glyph.  left_overhang part has already
+         drawn when s->prev was drawn, and right_overhang part will be
+         drawn later when s->next is drawn. */
+      x_set_glyph_string_clipping_exactly (s, s);
+      else
+        x_set_glyph_string_clipping (s);
+  switch (s->first_glyph->type)
+    {
+    case IMAGE_GLYPH:
+      x_draw_image_glyph_string (s);
+      break;
+    case XWIDGET_GLYPH:
+      x_draw_xwidget_glyph_string (s);
+      break;
+    case STRETCH_GLYPH:
+      mc_x_draw_stretch_glyph_string (s);
+      break;
+    case CHAR_GLYPH:
+      if (s->for_overlaps)
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, false);
+      x_draw_glyph_string_foreground (s);
+      break;
+    case COMPOSITE_GLYPH:
+      if (s->for_overlaps || (s->cmp_from > 0
+                              && ! s->first_glyph->u.cmp.automatic))
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, true);
+      x_draw_composite_glyph_string_foreground (s);
+      break;
+    case GLYPHLESS_GLYPH:
+      if (s->for_overlaps)
+        s->background_filled_p = true;
+      else
+        x_draw_glyph_string_background (s, true);
+      x_draw_glyphless_glyph_string_foreground (s);
+      break;
+    default:
+      emacs_abort ();
+    }
+  if (!s->for_overlaps)
+    {
+      /* Draw underline. */
+      if (s->face->underline_p)
+        {
+          if (s->face->underline_type == FACE_UNDER_WAVE)
+            {
+              if (s->face->underline_defaulted_p)
+                x_draw_underwave (s);
+              else
+                {
+                  XGCValues xgcv;
+                  XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+                  XSetForeground (s->display, s->gc, s->face->underline_color);
+                  x_draw_underwave (s);
+                  XSetForeground (s->display, s->gc, xgcv.foreground);
+                }
+            }
+          else if (s->face->underline_type == FACE_UNDER_LINE)
+            {
+              unsigned long thickness, position;
+              int y;
+              if (s->prev && s->prev->face->underline_p
+                  && s->prev->face->underline_type == FACE_UNDER_LINE)
+                {
+                  /* We use the same underline style as the previous one. */
+                  thickness = s->prev->underline_thickness;
+                  position = s->prev->underline_position;
+                }
+              else
+                {
+                  /* Get the underline thickness.  Default is 1 pixel. */
+                  if (s->font && s->font->underline_thickness > 0)
+                    thickness = s->font->underline_thickness;
+                  else
+                    thickness = 1;
+                  if (x_underline_at_descent_line)
+                    position = (s->height - thickness) - (s->ybase - s->y);
+                  else
+                    {
+                      /* Get the underline position.  This is the recommended
+                         vertical offset in pixels from the baseline to the top of
+                         the underline.  This is a signed value according to the
+                         specs, and its default is
+                         ROUND ((maximum descent) / 2), with
+                         ROUND(x) = floor (x + 0.5)  */
+                      if (x_use_underline_position_properties
+                          && s->font && s->font->underline_position >= 0)
+                        position = s->font->underline_position;
+                      else if (s->font)
+                        position = (s->font->descent + 1) / 2;
+                      else
+                        position = underline_minimum_offset;
+                    }
+                  position = max (position, underline_minimum_offset);
+                }
+              /* Check the sanity of thickness and position.  We should
+                 avoid drawing underline out of the current line area. */
+              if (s->y + s->height <= s->ybase + position)
+                position = (s->height - 1) - (s->ybase - s->y);
+              if (s->y + s->height < s->ybase + position + thickness)
+                thickness = (s->y + s->height) - (s->ybase + position);
+              s->underline_thickness = thickness;
+              s->underline_position = position;
+              y = s->ybase + position;
+              if (s->face->underline_defaulted_p)
+                x_fill_rectangle (s->f, s->gc, s->x, y, s->width, thickness);
+              else
+                {
+                  XGCValues xgcv;
+                  XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+                  XSetForeground (s->display, s->gc, s->face->underline_color);
+                  x_fill_rectangle (s->f, s->gc, s->x, y, s->width, thickness);
+                  XSetForeground (s->display, s->gc, xgcv.foreground);
+                }
+            }
+        }
+      /* Draw overline. */
+      if (s->face->overline_p)
+        {
+          unsigned long dy = 0, h = 1;
+          if (s->face->overline_color_defaulted_p)
+            x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, s->width, h);
+          else
+            {
+              XGCValues xgcv;
+              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+              XSetForeground (s->display, s->gc, s->face->overline_color);
+              x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, s->width, h);
+              XSetForeground (s->display, s->gc, xgcv.foreground);
+            }
+        }
+      /* Draw strike-through. */
+      if (s->face->strike_through_p)
+        {
+          unsigned long h = 1;
+          unsigned long dy = (s->height - h) / 2;
+          if (s->face->strike_through_color_defaulted_p)
+            x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, s->width, h);
+          else
+            {
+              XGCValues xgcv;
+              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
+              XSetForeground (s->display, s->gc, s->face->strike_through_color);
+              x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, s->width, h);
+              XSetForeground (s->display, s->gc, xgcv.foreground);
+            }
+        }
+      /* Draw relief if not yet drawn. */
+      if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
+          x_draw_glyph_string_box (s);
+      if (s->prev)
+        {
+          struct glyph_string *prev;
+          for (prev = s->prev; prev; prev = prev->prev)
+            if (prev->hl != s->hl
+                && prev->x + prev->width + prev->right_overhang > s->x)
+              {
+                /* As prev was drawn while clipped to its own area, we
+                   must draw the right_overhang part using s->hl now. */
+                enum draw_glyphs_face save = prev->hl;
+                prev->hl = s->hl;
+                mc_x_set_glyph_string_gc (prev, cursor_gc_p);
+                x_set_glyph_string_clipping_exactly (s, prev);
+                if (prev->first_glyph->type == CHAR_GLYPH)
+                  x_draw_glyph_string_foreground (prev);
+                else
+                  x_draw_composite_glyph_string_foreground (prev);
+                x_reset_clip_rectangles (prev->f, prev->gc);
+                prev->hl = save;
+                prev->num_clips = 0;
+              }
+        }
+      if (s->next)
+        {
+          struct glyph_string *next;
+          for (next = s->next; next; next = next->next)
+            if (next->hl != s->hl
+                && next->x - next->left_overhang < s->x + s->width)
+              {
+                /* As next will be drawn while clipped to its own area,
+                   we must draw the left_overhang part using s->hl now. */
+                enum draw_glyphs_face save = next->hl;
+                next->hl = s->hl;
+                mc_x_set_glyph_string_gc (next, cursor_gc_p);
+                x_set_glyph_string_clipping_exactly (s, next);
+                if (next->first_glyph->type == CHAR_GLYPH)
+                  x_draw_glyph_string_foreground (next);
+                else
+                  x_draw_composite_glyph_string_foreground (next);
+                x_reset_clip_rectangles (next->f, next->gc);
+                next->hl = save;
+                next->num_clips = 0;
+                next->clip_head = s->next;
+              }
+        }
+    }
+  /* Reset clipping. */
+  x_reset_clip_rectangles (s->f, s->gc);
+  s->num_clips = 0;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Default to using XIM if available.  */
 #ifdef USE_XIM
 bool use_xim = true;
@@ -999,6 +1878,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;
@@ -1266,6 +2154,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
@@ -13100,6 +13998,20 @@ x_activate_timeout_atimer (void)
 
 static struct redisplay_interface x_redisplay_interface =
   {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+/* `redisplay_interface' in `xterm.c` must be in the exact same order as the
+`redisplay_interface' in `dispextern.h`! */
+
+  mc_x_draw_window_cursor,
+  mc_x_draw_glyph_string,
+
+/* *************************************************************************** */
+
+
     x_frame_parm_handlers,
     x_produce_glyphs,
     x_write_glyphs,
