diff --git a/lisp/crosshairs.el b/lisp/crosshairs.el
new file mode 100644
index 0000000..3bbd697
--- /dev/null
+++ b/lisp/crosshairs.el
@@ -0,0 +1,1282 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 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)))
+
+(when (and (locate-library "multiple-cursors-core")
+           (not (featurep 'multiple-cursors-core)))
+  (require '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)
+      (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..9e5d51e 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2500,6 +2500,310 @@ unwanted effects."
   :group 'basic-faces
   :group 'display-line-numbers)
 
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; begin MULTIPLE-CURSORS
+
+(defface +-debugging-face
+  '((t (:foreground "OrangeRed")))
+  "Face for `+-debugging-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-special-character-face
+  '((t (:foreground "cyan")))
+  "Face for `+-special-character-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-vertical-bar-face
+  '((t (:foreground "magenta")))
+  "Face for `+-vertical-bar-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-reversed-vertical-bar-face
+  '((t (:foreground "cyan")))
+  "Face for `+-reversed-vertical-bar-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-even-numbered-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "DarkCyan")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "DarkCyan")
+    (((class color) (min-colors 88) (background light))
+     :foreground "DarkCyan")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-numbered-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-odd-numbered-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "red")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "red")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "red")
+    (((class color) (min-colors 88) (background light))
+     :foreground "red")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-numbered-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-even-numbered-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#eee8aa")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "blue")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "blue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "blue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-even-numbered-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-odd-numbered-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff6347")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "orange")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "orange")
+    (((class color) (min-colors 88) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-odd-numbered-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-beyond-fill-column-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "green")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "green")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "green")
+    (((class color) (min-colors 88) (background light))
+     :foreground "green")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-beyond-fill-column-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-beyond-fill-column-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 88) (background light))
+     :foreground "#2e8b57")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `+-beyond-fill-column-inactive-face'.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "cyan" :background "DarkBlue")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "magenta" :background "LightSkyBlue")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "magenta" :background "LightSkyBlue")
+    (((class color) (min-colors 88) (background light))
+     :foreground "magenta" :background "LightSkyBlue")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the border and
+the :background parameter is used for the inner filled shading.  The character
+retains its own foreground color and is unaffected by this particular face."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "#ff00ff" :background "ForestGreen")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "OrangeRed" :background "grey70")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "OrangeRed" :background "grey70")
+    (((class color) (min-colors 88) (background light))
+     :foreground "OrangeRed" :background "grey70")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-inactive-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the border and
+the :background parameter is used for the inner filled shading.  The character
+retains its own foreground color and is unaffected by this particular face."
+  :group '+-mode)
+
+(defface +-real-fake-cursor-region-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "chocolate4" :background "#8b795e")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "pink" :background "black")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "pink" :background "black")
+    (((class color) (min-colors 88) (background light))
+     :foreground "pink" :background "black")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow" :background "blue3")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange" :background "lightgoldenrod2")
+    (((class color) (min-colors 8))
+     :foreground "white" :background "blue")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink" :background "gray"))
+  "Face for `+-real-fake-cursor-region-face'.  Used in `xdisp.c'.
+As to a hollow style cursor, the :foreground parameter is used for the inner
+filled shading when PT is _not_ within the active region; and, the :background
+parameter is used for the inner filled shading when PT _is_ within the active
+region.  The character retains its own foreground color and is unaffected by this
+particular face."
+  :group '+-mode)
+
+(defface +-overlay-arrow-face
+  '((t (:foreground "red")))
+  "Face for `+-overlay-arrow-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-inactive-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-inactive-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-face
+  '((t (:foreground "DarkGreen")))
+  "Face for `+-overlay-arrow-hscl-face'."
+  :group '+-mode)
+
+(defface +-overlay-arrow-hscl-inactive-face
+  '((t (:foreground "DarkSlateGrey")))
+  "Face for `+-overlay-arrow-hscl-inactive-face'."
+  :group '+-mode)
+
+(defface fc-face
+  '((((class color) (min-colors 88) (background dark) (type ns))
+     :foreground "grey15")
+    (((class color) (min-colors 88) (background dark) (type gtk))
+         :foreground "grey15")
+    (((class color) (min-colors 88) (background dark) (type w32))
+         :foreground "grey25")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "purple")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "purple")
+    (((class color) (min-colors 88) (background light))
+     :foreground "purple")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-face' in the active window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface fc-inactive-face
+  '((((class color) (min-colors 88) (background dark))
+     :foreground "DarkBlue")
+    (((class color) (min-colors 88) (background light) (type gtk))
+     :foreground "grey15")
+    (((class color) (min-colors 88) (background light) (type ns))
+     :foreground "grey15")
+    (((class color) (min-colors 88) (background light))
+     :foreground "grey15")
+    (((class color) (min-colors 16) (background dark))
+     :foreground "yellow")
+    (((class color) (min-colors 16) (background light))
+     :foreground "orange")
+    (((class color) (min-colors 8))
+     :foreground "white")
+    (((type tty) (class mono))
+     :inverse-video t)
+    (t :foreground "pink"))
+  "Face for `fc-inactive-face' in the inactive window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface fc-opoint-face
+  '((t (:foreground "magenta")))
+  "Face for `fc-opoint-face' in the active window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+(defface fc-opoint-inactive-face
+  '((t (:foreground "cyan")))
+  "Face for `fc-opoint-inactive-face' in the inactive window.  Used in `xdisp.c'."
+  :group '+-mode)
+
+;;; end MULTIPLE-CURSORS
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
 (defface escape-glyph
   '((((background dark)) :foreground "cyan")
     ;; See the comment in minibuffer-prompt for
diff --git a/src/buffer.c b/src/buffer.c
index 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..d689a2d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -100,6 +100,36 @@ typedef int Cursor;
 #define NativeRectangle int
 #endif
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+/* Forward prototype definitions. */
+enum type_of_cache;
+
+enum type_of_cursor;
+
+enum mc_flavor;
+
+enum type_of_action
+{
+  MULTIPLE_CURSORS,
+  HORIZONTAL_RULER,
+  VERTICAL_RULER,
+  FILL_COLUMN
+};
+
+struct mc_RGB
+{
+  double red;
+  double green;
+  double blue;
+};
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Text cursor types.  */
 
 enum text_cursor_kinds
@@ -382,6 +412,20 @@ struct glyph_slice
 
 struct glyph
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  int x, y, hpos, vpos;
+
+  int relative_x;
+
+  bool_bf zv_p : 1;
+
+/* *************************************************************************** */
+
+
   /* Position from which this glyph was drawn.  If `object' below is a
      Lisp string, this is an index into that string.  If it is a
      buffer, this is a position in that buffer.  In addition, some
@@ -1248,6 +1292,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,
+      MC_ERASE_GLYPH
+    } action_type;
+
+/* *************************************************************************** */
+
+
   /* X-origin of the string.  */
   int x;
 
@@ -2216,6 +2282,16 @@ struct composition_it
 
 struct it
 {
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  bool_bf zv_p : 1;
+
+/* *************************************************************************** */
+
+
   /* The window in which we iterate over current_buffer (or a string).  */
   Lisp_Object window;
   struct window *w;
@@ -2812,6 +2888,31 @@ 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`! */
+
+  void (*mc_scribe_glyphs) (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+        struct glyph *string, enum glyph_row_area area, int len, int vpos,
+        int bottom_vpos, struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+        enum type_of_cursor cursor_type, int wd, bool active_p, bool cursor_gc_p);
+
+  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 type_of_cursor cursor_type,
+        int cursor_width, enum mc_flavor glyph_flavor, bool on_p, bool active_p);
+
+  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 type_of_cursor cursor_type, int wd, bool active_p, bool cursor_gc_p);
+
+/* *************************************************************************** */
+
+
   /* Handlers for setting frame parameters.  */
   frame_parm_handler *frame_parm_handlers;
 
@@ -3270,6 +3371,67 @@ extern void get_font_ascent_descent (struct font *, int *, int *);
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+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 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 type_of_cursor);
+
+extern char * mc_flavor_to_string (enum mc_flavor);
+
+extern void mc_draw_fringe_bitmap (struct window *, struct glyph_row *, int,
+                                   enum type_of_cursor);
+
+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 type_of_cursor, int, struct glyph_matrix *, int,
+                       struct mc_RGB, bool, enum type_of_action, bool,
+                       enum type_of_cache);
+
+extern void mc_set_essentials (struct window *, bool, struct mc_RGB *,
+                               struct mc_RGB *, int *);
+
+extern void mc_draw_row (struct window *, struct glyph_matrix *, struct glyph_row *,
+                         struct glyph *, int, int, int, int, bool, struct glyph_matrix *,
+                         int, struct mc_RGB, struct mc_RGB, bool);
+
+extern void mc_redraw_row (struct window *, struct glyph_matrix *, struct glyph_row *,
+                           int, int, int, bool, enum draw_glyphs_face);
+
+extern void mc_reset_cache (struct window *, enum type_of_cache);
+
+extern void mc_pre_scroll_clean (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 type_of_cursor, int, bool, bool);
+
+extern void mc_x_write_glyphs (struct window *, struct glyph_matrix *, struct glyph_row *,
+                               struct glyph *, enum glyph_row_area, int,
+                               int, int, struct mc_RGB, enum mc_flavor,
+                               enum type_of_cursor, int, bool, bool);
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 #ifdef GLYPH_DEBUG
 extern void dump_glyph_string (struct glyph_string *) EXTERNALLY_VISIBLE;
 #endif
diff --git a/src/dispnew.c b/src/dispnew.c
index ccb08ec..60f316d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -56,6 +56,468 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "w32.h"
 #endif
 
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+struct mc_RGB ch_foreground = {.red = -1.0, .green = -1.0, .blue = -1.0};
+
+struct mc_RGB fc_foreground = {.red = -1.0, .green = -1.0, .blue = -1.0};
+
+int fc_x = 0;
+
+struct glyph_matrix *cursor_matrix;
+
+struct glyphs_skipped
+{
+  ptrdiff_t allocated;
+  ptrdiff_t used;
+  struct skipped_items
+    {
+      int x;
+      int hpos;
+      bool enabled_p;
+    } *skipped;
+};
+
+struct glyphs_skipped array_glyphs_skipped;
+
+/* 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)
+{
+  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)));
+  struct frame *f = XFRAME (w->frame);
+  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 type_of_cursor cursor_type = 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;
+  struct glyph_matrix *desired_matrix = w->desired_matrix;
+  struct glyph_row *bottom_row = MATRIX_BOTTOM_TEXT_ROW (desired_matrix, w);
+  int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, desired_matrix);
+  if (debug_p
+      && vpos != bottom_vpos)
+    fprintf (stderr, "mc_update_text_area (%s):  vpos (%d) | bottom_vpos (%d)\n",
+                      mc_window (w), vpos, bottom_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
+      && vpos != bottom_vpos)
+    {
+      fprintf (stderr, "WRITE ENTIRE ROW:\n\
+      char (%d/%s) | start_x: (%d) | start_hpos (%d) | length (%d) | vpos (%d)\n",
+      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], vpos);
+    }
+      if (desired_row->used[TEXT_AREA])
+        rif->mc_scribe_glyphs (w, desired_matrix, updated_row, desired_row->glyphs[TEXT_AREA],
+                               TEXT_AREA, desired_row->used[TEXT_AREA], vpos,
+                               bottom_vpos, lsl, glyph_flavor, cursor_type, wd,
+                               active_p, cursor_gc_p);
+
+      /* Clear to end of window. */
+      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, bottom_vpos,
+               active_p, cursor_matrix, fc_x, ch_foreground, fc_foreground, true);
+    }
+  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
+       && vpos != bottom_vpos;
+       ++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:  char (%d/%s) | x: (%d) | hpos (%d) | vpos (%d)\n",
+                         target_glyph->u.ch, mc_char_to_string (target_glyph->u.ch),
+                         x, hpos, vpos);
+      mc_draw_row (w, desired_matrix, updated_row, target_glyph, x, 1, vpos,
+                   bottom_vpos, active_p, cursor_matrix, fc_x, ch_foreground,
+                   fc_foreground, true);
+    }
+
+        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
+      && vpos != bottom_vpos)
+    {
+      fprintf (stderr, "REDRAW SEGMENT:\n\
+      char (%d/%s) | start_x: (%d) | start_hpos (%d) | length (%d) | vpos (%d)\n",
+      start->u.ch, mc_char_to_string (start->u.ch),
+      start_x, start_hpos, i - start_hpos, vpos);
+    }
+
+  rif->mc_scribe_glyphs (w, desired_matrix, updated_row, start, TEXT_AREA, i - start_hpos,
+                         vpos, bottom_vpos, lsl,
+                         glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+
+  mc_draw_row (w, desired_matrix, updated_row, start, start_x, i - start_hpos,
+               vpos, bottom_vpos, active_p, cursor_matrix, fc_x, ch_foreground,
+               fc_foreground, true);
+
+        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
+      && vpos != bottom_vpos)
+    {
+      fprintf (stderr, "DRAW REMAINDER OF THE ROW:\n\
+      char (%d/%s) | x: (%d) | i (%d) | length (%d) | vpos (%d)\n",
+      desired_glyph->u.ch, mc_char_to_string (desired_glyph->u.ch),
+      x, i, desired_row->used[TEXT_AREA] - i, vpos);
+    }
+
+  rif->mc_scribe_glyphs (w, desired_matrix, updated_row, desired_glyph, TEXT_AREA, desired_row->used[TEXT_AREA] - i,
+                         vpos, bottom_vpos, lsl,
+                         glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+
+  /* 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, bottom_vpos, active_p,
+               cursor_matrix, fc_x, ch_foreground, fc_foreground, true);
+
+    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)
+      {
+        int x = w->output_cursor.x;
+        int hpos = (w->output_cursor.hpos == updated_row->used[TEXT_AREA])
+                   ? updated_row->used[TEXT_AREA] - 1
+                   : 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, "CHANGED - FROM:  char (%d/%s) | x (%d) | hpos (%d) -- TO END.\n",
+                           start->u.ch, mc_char_to_string (start->u.ch), x, hpos);
+        mc_draw_row (w, desired_matrix, updated_row, start, x,
+                     updated_row->used[TEXT_AREA] - hpos, vpos, bottom_vpos,
+                     active_p, cursor_matrix, fc_x, ch_foreground, fc_foreground,
+                     true);
+      }
+      /* There were no changes and i == desired_row->used[TEXT_AREA] */
+      else if (!changed_p)
+        {
+          if (debug_p)
+            fprintf (stderr, "UNCHANGED -- WRITE ENTIRE LINE.\n");
+          mc_draw_row (w, desired_matrix, updated_row, desired_row->glyphs[TEXT_AREA],
+                       desired_row->x, desired_row->used[TEXT_AREA], vpos,
+                       bottom_vpos, active_p, cursor_matrix, fc_x, ch_foreground,
+                       fc_foreground, true);
+        }
+
+      /* 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);
+          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;
+          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;
+      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 (XBUFFER (w->contents), crosshairs))
+          && !NILP (BVAR (XBUFFER (w->contents), ch_horizontal_ruler))
+          && x < text_area_width
+          && vpos == w->cursor.vpos
+          && target_glyph != NULL)
+        mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA, x, x_limit,
+                   updated_row->y, hpos, vpos, MC_HBAR, 1, cursor_matrix, fc_x,
+                   debug_p ? debug_fg : ch_foreground, active_p, HORIZONTAL_RULER,
+                   true, NO_CACHE);
+
+      if (BUFFERP (w->contents)
+          && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          && !NILP (BVAR (XBUFFER (w->contents), ch_vertical_ruler))
+          && x < text_area_width
+          && vpos != w->cursor.vpos
+          && w->cursor.x >= x
+          && target_glyph != NULL)
+        mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA, x, x_limit,
+                   updated_row->y, hpos, vpos, MC_BAR, 1, cursor_matrix, fc_x,
+                   debug_p ? debug_fg : ch_foreground, active_p, VERTICAL_RULER,
+                   true, NO_CACHE);
+
+      if (BUFFERP (w->contents)
+          && !NILP (BVAR (XBUFFER (w->contents), fc_visible))
+          && x < text_area_width
+          && fc_x >= x
+          && target_glyph != NULL)
+        mc_engine (w, desired_matrix, updated_row, target_glyph, TEXT_AREA, x, x_limit,
+                   updated_row->y, hpos, vpos, MC_BAR, 1, cursor_matrix, fc_x,
+                   debug_p ? debug_fg : fc_foreground, active_p, FILL_COLUMN,
+                   true, NO_CACHE);
+
+    }
+    }
+  return changed_p;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* Structure to pass dimensions around.  Used for character bounding
    boxes, glyph matrix dimensions and alike.  */
 
@@ -3282,10 +3744,36 @@ redraw_overlapped_rows (struct window *w, int yb)
 	    {
 	      output_cursor_to (w, i, 0, row->y,
 				area == TEXT_AREA ? row->x : 0);
-	      if (row->used[area])
+
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if ((w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+      && area == TEXT_AREA
+      && row->used[area])
+    {
+      struct glyph_matrix *matrix = w->current_matrix;
+      int start_x = row->x;
+      int start_hpos = 0;
+      int end_hpos = row->used[area];
+      bool clear_eol_p = true;
+      enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+      TRACE ((stderr, "redraw_overlapped_rows (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+                      i, start_x, start_hpos, end_hpos));
+      mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+    }
+    else if (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;
@@ -3388,6 +3876,28 @@ static bool
 update_window (struct window *w, bool force_p)
 {
   struct glyph_matrix *desired_matrix = w->desired_matrix;
+
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+  if (trace_redisplay_p)
+    fprintf (stderr, "update_window (%s)\n", mc_window (w));
+
+  cursor_matrix = NULL;
+
+  struct frame *f = XFRAME (w->frame);
+  bool active_p = (w == XWINDOW (f->selected_window)
+                   && f == FRAME_DISPLAY_INFO (f)->x_highlight_frame);
+
+  mc_set_essentials (w, active_p, &ch_foreground, &fc_foreground, &fc_x);
+
+  mc_pre_scroll_clean (w);
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
   bool paused_p;
   int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -3460,6 +3970,41 @@ 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 |= 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 +4012,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 proceed
+  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
@@ -3497,6 +4055,43 @@ 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 *bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+     int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, w->current_matrix);
+     struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, 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,
+                    bottom_vpos, active_p, cursor_matrix, fc_x, ch_foreground,
+                    fc_foreground, true);
+   }
+
+/* *************************************************************************** */
+
+
       /* 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.  */
@@ -3531,10 +4126,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
@@ -3852,14 +4458,28 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
 	  current_row->redraw_fringe_bitmaps_p = 1;
 	}
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  bool updated_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_text_area (w, desired_row, vpos)
+                   : update_text_area (w, desired_row, vpos);
+
       /* Update the display of the text area.  */
-      if (update_text_area (w, desired_row, vpos))
+      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)
 	{
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..0dbea5f 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,1044 @@ 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 vpos_desired = MATRIX_ROW_VPOS (w->desired_matrix->rows + rn, w->desired_matrix);
+  int vpos_current = MATRIX_ROW_VPOS (w->current_matrix->rows + rn, w->current_matrix);
+  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;
+  for (int elt = 0; elt < w->ch_elts.used; ++elt)
+    {
+      int x = w->ch_elts.caches[elt].x;
+      int fx = w->ch_elts.caches[elt].fx;
+      int y = w->ch_elts.caches[elt].y;
+      int fy = w->ch_elts.caches[elt].fy;
+      int hpos = w->ch_elts.caches[elt].hpos;
+      int vpos = w->ch_elts.caches[elt].vpos;
+      int wd = w->ch_elts.caches[elt].wd;
+      int h = w->ch_elts.caches[elt].h;
+      enum type_of_cursor cursor_type = w->ch_elts.caches[elt].cursor_type;
+      int cursor_width = w->ch_elts.caches[elt].cursor_width;
+      struct mc_RGB lsl_fg = {.red = w->ch_elts.caches[elt].foreground.red,
+                              .green = w->ch_elts.caches[elt].foreground.green,
+                              .blue = w->ch_elts.caches[elt].foreground.blue};
+      struct mc_RGB lsl_bg = {.red = w->ch_elts.caches[elt].background.red,
+                              .green = w->ch_elts.caches[elt].background.green,
+                              .blue = w->ch_elts.caches[elt].background.blue};
+      bool active_p = w->ch_elts.caches[elt].active_p;
+      enum mc_flavor glyph_flavor = w->ch_elts.caches[elt].glyph_flavor;
+      bool enabled_p = w->ch_elts.caches[elt].enabled_p;
+      if ((vpos == vpos_desired || vpos == vpos_current)
+          && 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-face"), true)
+            : (active_p)
+              ? lookup_named_face (w, f, intern ("+-overlay-arrow-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 == vpos_desired || vpos == vpos_current)
+                 && 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-face"), true)
+              : (active_p)
+                ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-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 == vpos_desired || vpos == vpos_current)
+                    && (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
+                 && (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-vertical-bar-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 ("+-vertical-bar-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 type_of_cursor 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 +3190,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..a01fb93 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -76,6 +76,1091 @@ Updated by Christian Limpach (chris@nice.ch)
 static EmacsMenu *mainMenu;
 #endif
 
+
+/* *************************************************************************** */
+/* begin MULTIPLE-CURSORS */
+
+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;
+}
+
+/* Needed for a current version of Emacs master branch. */
+BOOL
+mc_ns_intersect_rectangles (NSRect *r1, NSRect *r2, NSRect *result)
+{
+  NSRect *left, *right;
+  NSRect *upper, *lower;
+  bool intersection_p = false;
+  /* Rearrange so that R1 is the left-most rectangle.  */
+  if (r1->origin.x < r2->origin.x)
+    left = r1, right = r2;
+  else
+    left = r2, right = r1;
+  /* X0 of the intersection is right.x0, if this is inside R1,
+     otherwise there is no intersection.  */
+  if (right->origin.x <= left->origin.x + left->size.width)
+    {
+      result->origin.x = right->origin.x;
+      /* The right end of the intersection is the minimum of
+   the right ends of left and right.  */
+      result->size.width = (min (left->origin.x + left->size.width, right->origin.x + right->size.width)
+           - result->origin.x);
+      /* Same game for Y.  */
+      if (r1->origin.y < r2->origin.y)
+  upper = r1, lower = r2;
+      else
+  upper = r2, lower = r1;
+      /* The upper end of the intersection is lower.y0, if this is inside
+   of upper.  Otherwise, there is no intersection.  */
+      if (lower->origin.y <= upper->origin.y + upper->size.height)
+  {
+    result->origin.y = lower->origin.y;
+    /* The lower end of the intersection is the minimum of the lower
+       ends of upper and lower.  */
+    result->size.height = (min (lower->origin.y + lower->size.height,
+                                upper->origin.y + upper->size.height)
+                           - result->origin.y);
+    intersection_p = true;
+  }
+    }
+  return intersection_p;
+}
+
+/* Needed for a current version of Emacs master branch. */
+static BOOL
+mc_ns_clip_to_rect (struct frame *f, NSRect *r, int n, struct glyph_row *row)
+/* --------------------------------------------------------------------------
+   Clip the drawing area to rectangle r in frame f.  If drawing is not
+   currently possible mark r as dirty and return NO, otherwise return YES.
+   Take into consideration `row->clip` if it was set by `expose_window'.
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "mc_ns_clip_to_rect");
+  if (r)
+    {
+      NSTRACE_RECT ("r", *r);
+      if ([NSView focusView] == FRAME_NS_VIEW (f))
+        {
+          [[NSGraphicsContext currentContext] saveGraphicsState];
+          if (n == 2)
+            NSRectClipList (r, 2);
+            else
+              {
+                if (row->clip != NULL)
+                  {
+                    NSRect r_clip;
+                    r_clip.origin.x = row->clip->x;
+                    r_clip.origin.y = row->clip->y;
+                    r_clip.size.width = row->clip->width;
+                    r_clip.size.height = row->clip->height;
+                    NSRect r_save;
+                    r_save.origin.x = r[0].origin.x;
+                    r_save.origin.y = r[0].origin.y;
+                    r_save.size.width = r[0].size.width;
+                    r_save.size.height = r[0].size.height;
+                    mc_ns_intersect_rectangles (&r_save, &r_clip, &r[0]);
+                  }
+                NSRectClip (*r);
+              }
+          return YES;
+        }
+      else
+        {
+          NSView *view = FRAME_NS_VIEW (f);
+          int i;
+          for (i = 0 ; i < n ; i++)
+            [view setNeedsDisplayInRect:r[i]];
+        }
+    }
+  return NO;
+}
+
+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 type_of_cursor 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;
+  if (!mc_ns_clip_to_rect (f, &r, 1, row))
+    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 ("+-vertical-bar-face"), true);
+     struct face *face = FACE_FROM_ID (f, face_id);
+     NSColor *color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f);
+  -  EXAMPLE OF HOW TO PRINT A COLOR TO STDERR:
+     Lisp_Object foreground = face->lface[LFACE_FOREGROUND_INDEX];
+     Lisp_Object background = face->lface[LFACE_BACKGROUND_INDEX];
+     fprintf (stderr, "\nforeground (%s) | background (%s)\n",
+                      (!NILP (foreground) ? SSDATA (foreground) : "NILP"),
+                      (!NILP (background) ? SSDATA (background) : "NILP"));
+  -  EXAMPLE OF HOW TO CREATE A COLOR WITH RGB/LSL float values:
+     NSColor *my_color = [NSColor colorWithCalibratedRed: 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_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+      ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+      ptrdiff_t opoint_pt = (w == XWINDOW (selected_window))
+                            ? PT
+                            : XFIXNUM (Fmarker_position (w->pointm));
+      bool region_in_bounds_p = (region_active_p
+                                 && opoint_pt >= region_beginning
+                                 && opoint_pt < region_end);
+      if (region_active_p
+          && region_in_bounds_p
+          && active_p)
+        {
+          enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+          struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+          NSColor *hollow_active_region_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_region_face), f);
+          hollow_color = hollow_active_region_color;
+        }
+        else if (region_active_p
+                 && !region_in_bounds_p
+                 && active_p)
+          {
+            enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+            struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+            NSColor *hollow_active_region_out_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_out_face), f);
+            hollow_color = hollow_active_region_out_color;
+          }
+          else if (!region_active_p && active_p)
+            {
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+              struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+              NSColor *hollow_active_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_face), f);
+              hollow_color = hollow_active_color;
+            }
+            /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+            else if (!active_p)
+              {
+                enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                NSColor *hollow_inactive_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_inactive_face), f);
+                hollow_color = hollow_inactive_color;
+              }
+    }
+    else if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (f), f))
+      {
+        [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;
+      mc_draw_cursor_glyph (w, matrix, row, DRAW_CURSOR, x, hpos, vpos, lsl,
+                            glyph_flavor, cursor_type, wd, active_p, cursor_gc_p);
+    }
+#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, int wd, struct glyph_row *row)
+{
+  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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+        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);
+        }
+      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 type_of_cursor 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_overwritten_helper (struct glyph_string *s, struct glyph_matrix *matrix,
+                          struct glyph_row *row, enum type_of_cache cache_type,
+                          struct glyph *glyph)
+{
+  // 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 row_vpos = MATRIX_ROW_VPOS (row, matrix);
+  struct multiple_cursors_cache foo_elts;
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          foo_elts.caches = s->w->mc_elts.caches;
+          foo_elts.allocated = s->w->mc_elts.allocated;
+          foo_elts.used = s->w->mc_elts.used;
+          break;
+        }
+      case CH_CACHE:
+        {
+          foo_elts.caches = s->w->ch_elts.caches;
+          foo_elts.allocated = s->w->ch_elts.allocated;
+          foo_elts.used = s->w->ch_elts.used;
+          break;
+        }
+      case FC_CACHE:
+        {
+          foo_elts.caches = s->w->fc_elts.caches;
+          foo_elts.allocated = s->w->fc_elts.allocated;
+          foo_elts.used = s->w->fc_elts.used;
+          break;
+        }
+    }
+  /* STRETCH_GLYPH may contain more than one fake cursor at the same HPOS. */
+  for (int elt = 0; elt < foo_elts.used; ++elt)
+    {
+      int x = foo_elts.caches[elt].x;
+      int fx = foo_elts.caches[elt].fx;
+      int y = foo_elts.caches[elt].y;
+      int fy = foo_elts.caches[elt].fy;
+      int hpos = foo_elts.caches[elt].hpos;
+      int vpos = foo_elts.caches[elt].vpos;
+      int wd = foo_elts.caches[elt].wd;
+      int h = foo_elts.caches[elt].h;
+      enum type_of_cursor cursor_type = foo_elts.caches[elt].cursor_type;
+      int cursor_width = foo_elts.caches[elt].cursor_width;
+      struct mc_RGB lsl_fg = {.red = foo_elts.caches[elt].foreground.red,
+                              .green = foo_elts.caches[elt].foreground.green,
+                              .blue = foo_elts.caches[elt].foreground.blue};
+      struct mc_RGB lsl_bg = {.red = foo_elts.caches[elt].background.red,
+                              .green = foo_elts.caches[elt].background.green,
+                              .blue = foo_elts.caches[elt].background.blue};
+      bool active_p = foo_elts.caches[elt].active_p;
+      enum mc_flavor glyph_flavor = foo_elts.caches[elt].glyph_flavor;
+      bool enabled_p = foo_elts.caches[elt].enabled_p;
+      bool go_p = (vpos == row_vpos
+                   && hpos == 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_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+      ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+      ptrdiff_t opoint_pt = (s->w == XWINDOW (selected_window))
+                            ? PT
+                            : XFIXNUM (Fmarker_position (s->w->pointm));
+      bool region_in_bounds_p = (region_active_p
+                                 && opoint_pt >= region_beginning
+                                 && opoint_pt < region_end);
+      if (region_active_p
+          && region_in_bounds_p
+          && active_p)
+        {
+          enum face_id hollow_active_region_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-region-face"), true);
+          struct face *hollow_active_region_face = FACE_FROM_ID (s->f, hollow_active_region_face_id);
+          NSColor *hollow_active_region_color = ns_lookup_indexed_color (NS_FACE_BACKGROUND (hollow_active_region_face), s->f);
+          hollow_color = hollow_active_region_color;
+        }
+        else if (region_active_p
+                 && !region_in_bounds_p
+                 && active_p)
+          {
+            enum face_id hollow_active_region_out_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-region-face"), true);
+            struct face *hollow_active_region_out_face = FACE_FROM_ID (s->f, hollow_active_region_out_face_id);
+            NSColor *hollow_active_region_out_color = ns_lookup_indexed_color (NS_FACE_FOREGROUND (hollow_active_region_out_face), s->f);
+            hollow_color = hollow_active_region_out_color;
+          }
+          else if (!region_active_p && active_p)
+            {
+              enum face_id hollow_active_face_id = lookup_named_face (s->w, s->f, intern ("+-real-fake-cursor-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;
+            }
+            /* 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 (s->w, s->f, intern ("+-real-fake-cursor-inactive-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);
+              }
+        }
+    }
+}
+
+static void
+mc_ns_draw_overwritten (struct glyph_string *s, struct glyph_matrix *matrix,
+                        struct glyph_row *row, struct glyph *glyph)
+{
+  //  int vpos = MATRIX_ROW_VPOS (row, matrix);
+  //  clock_t clock_start = clock();
+  mc_ns_overwritten_helper (s, matrix, row, MC_CACHE, glyph);
+  mc_ns_overwritten_helper (s, matrix, row, CH_CACHE, glyph);
+  mc_ns_overwritten_helper (s, matrix, row, FC_CACHE, glyph);
+  //  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_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 type_of_cursor cursor_type,
+                         int wd, bool active_p, bool cursor_gc_p)
+/* --------------------------------------------------------------------------
+      External (RIF): Main draw-text call.
+   -------------------------------------------------------------------------- */
+{
+  /* TODO (optimize): focus for box and contents draw */
+  NSRect r[2];
+  int n, flags;
+  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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+                  return;
+                mc_ns_maybe_dumpglyphs_background (s->next, 1);
+                ns_reset_clipping (s->f);
+              }
+            else
+              {
+                mc_ns_dumpglyphs_stretch (s->next, wd, row);
+                if ((s->next->left_overwritten_p || s->next->right_overwritten_p)
+                    && s->next->action_type == MC_DRAW_GLYPH)
+                  mc_ns_draw_overwritten (s->next, matrix, row, s->next->first_glyph);
+              }
+            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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+        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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+        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, wd, row);
+      if ((s->left_overwritten_p || s->right_overwritten_p)
+          && s->action_type == MC_DRAW_GLYPH)
+        mc_ns_draw_overwritten (s, matrix, row, s->first_glyph);
+      break;
+    case CHAR_GLYPH:
+    case COMPOSITE_GLYPH:
+      n = ns_get_glyph_string_clip_rect (s, r);
+      if (!mc_ns_clip_to_rect (s->f, r, n, row))
+        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);
+      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-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-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);
+            }
+      {
+        BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
+        if (isComposite)
+          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)
+          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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+        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);
+      /* ... */
+      /* Not yet implemented.  */
+      /* ... */
+      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 (!mc_ns_clip_to_rect (s->f, r, n, row))
+        return;
+      ns_dumpglyphs_box_or_relief (s);
+      ns_reset_clipping (s->f);
+    }
+  s->num_clips = 0;
+}
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 /* ==========================================================================
 
    NSTRACE, Trace support.
@@ -1109,6 +2194,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 +2304,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 +5908,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 +5926,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 +6109,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 +6288,21 @@ 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_x_write_glyphs,
+  mc_ns_draw_window_cursor,
+  mc_ns_draw_glyph_string,
+
+/* *************************************************************************** */
+
+
   ns_frame_parm_handlers,
   x_produce_glyphs,
   x_write_glyphs,
@@ -8721,6 +9918,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..6e995b7 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -62,6 +62,859 @@ 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 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 *);
+
+static
+void w32_draw_underwave (struct glyph_string *, COLORREF);
+
+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 type_of_cursor 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 type_of_cursor 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 type_of_cursor 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_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+      ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+      ptrdiff_t opoint_pt = (w == XWINDOW (selected_window))
+                            ? PT
+                            : XFIXNUM (Fmarker_position (w->pointm));
+      bool region_in_bounds_p = (region_active_p
+                                 && opoint_pt >= region_beginning
+                                 && opoint_pt < region_end);
+      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
+              && region_in_bounds_p
+              && active_p)
+            {
+              enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+              struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+              struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+              gc_values.foreground = hollow_active_face->foreground;
+              gc_values.background = hollow_active_region_face->background;
+            }
+            else if (region_active_p
+                     && !region_in_bounds_p
+                     && active_p)
+              {
+                enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                gc_values.foreground = hollow_active_face->foreground;
+                gc_values.background = hollow_active_region_out_face->foreground;
+              }
+              else if (!region_active_p && active_p)
+                {
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  gc_values.foreground = hollow_active_face->foreground;
+                  gc_values.background = hollow_active_face->background;
+                }
+                /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                else if (!active_p)
+                  {
+                    enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                    struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                    gc_values.foreground = 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
+                  && region_in_bounds_p
+                  && active_p)
+                {
+                  enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                  struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  gc_values.foreground = hollow_active_face->foreground;
+                  gc_values.background = hollow_active_region_face->background;
+                }
+                else if (region_active_p
+                         && !region_in_bounds_p
+                         && active_p)
+                  {
+                    enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                    struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                    struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                    gc_values.foreground = hollow_active_face->foreground;
+                    gc_values.background = hollow_active_region_out_face->foreground;
+                  }
+                  else if (!region_active_p && active_p)
+                    {
+                      enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                      struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                      gc_values.foreground = hollow_active_face->foreground;
+                      gc_values.background = hollow_active_face->background;
+                    }
+                    /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                    else if (!active_p)
+                      {
+                        enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                        struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                        gc_values.foreground = 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 type_of_cursor 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 +1398,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 +1616,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 +4913,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 +5249,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 +8039,21 @@ 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_x_write_glyphs,
+  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..f2975be 100644
--- a/src/window.h
+++ b/src/window.h
@@ -88,6 +88,84 @@ display the menu bar or the tool bar (when Emacs uses toolkits that
 don't display their own menu bar and tool bar) or a tooltip in a
 tooltip frame (when tooltips are not display by the toolkit).  */
 
+
+/* *************************************************************************** */
+/* 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;
+};
+
+struct multiple_cursors_cache
+{
+  ptrdiff_t allocated;
+  ptrdiff_t used;
+  enum type_of_cache
+    {
+      NO_CACHE,
+      MC_CACHE,
+      CH_CACHE,
+      FC_CACHE
+    } cache_type;
+  struct items_in_cache
+    {
+      int x;
+      int fx;
+      int y;
+      int fy;
+      int hpos;
+      int vpos;
+      int wd;
+      int h;
+      enum type_of_cursor
+        {
+          /* 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 RGB
+        {
+          double red;
+          double green;
+          double blue;
+        } foreground, background;
+      bool active_p;
+      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 enabled_p;
+    } *caches;
+};
+
+/* end MULTIPLE-CURSORS */
+/* *************************************************************************** */
+
+
 struct cursor_pos
 {
   /* Pixel position.  These are always window relative.  */
@@ -324,6 +402,21 @@ struct window
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+    struct multiple_cursors mc;
+
+    struct multiple_cursors_cache mc_elts;
+
+    struct multiple_cursors_cache ch_elts;
+
+    struct multiple_cursors_cache fc_elts;
+
+/* *************************************************************************** */
+
+
     /* Cursor type of last cursor drawn on the window.  */
     enum text_cursor_kinds phys_cursor_type;
 
@@ -1120,6 +1213,15 @@ extern void redisplay_other_windows (void);
 
 struct glyph *get_phys_cursor_glyph (struct window *w);
 
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+struct glyph *mc_get_cursor_glyph (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row, int hpos, int vpos);
+
+/* *************************************************************************** */
+
+
 /* True if WINDOW is a valid window.  */
 #define WINDOW_VALID_P(WINDOW)					\
   (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->contents))	\
diff --git a/src/xdisp.c b/src/xdisp.c
index a88fc69..282a543 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -921,6 +921,4100 @@ 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:
+
+- 019.002 [05/02/2019]
+- 019.001 [04/28/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:
+
+- Eliminated the usage of a Lisp_Object within `mc_update_text_area' in favor of
+  an array of structs.  [Every Lisp_Object that is eliminated will reduce the
+  need for garbage collection.]
+
+- Eliminated `mc/save-window-scroll' when using the multiple-crosshairs library
+  written by Magnar Sveen.  [Said function caused non-selected windows to be
+  updated during redisplay, resulting in undue slowdown.]
+
+- Miscellaneous changes regarding when/what stderr messages are to appear when
+  running M-x trace-redisplay; and, changed the name of the function responsible
+  for erasing fake cursors and resetting the cache:  `mc_pre_scroll_clean'.
+  Eliminated the message to run "M-x mc-install" when `crosshairs.el` loads.
+
+
+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 the crosshairs feature, type:  M-x +-mode
+
+- To try out built-in fake cursors with Magnar Sveen's multiple-cursors package,
+  install that package first.  [If the multiple-cursors package is installed, an
+  eval-after-load "multiple-cursors-core" statement within `crosshairs.el` will
+  redefine a couple of functions and set up a few keyboard shortcuts.]  If the
+  multiple-cursors package by Magnar Sveen is not already installed, then 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))
+
+
+TODO:
+
+- Add support for `ch_inactive_windows' and `fc_inactive_windows'.
+
+- When using the multiple fake cursors feature, a fake cursor does not show up at
+  zv_p.
+
+- Deal with left/right overwritten glyphs in the w32 and X ports of Emacs.
+
+- Reduce the removal of fake cursors to the bare minimum when scrolling the text
+  on the glass directly, and whenever `update_window' is called.
+
+- 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
+  an minimal working example and file a bug report.
+
+- 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.]
+
+- 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.
+
+
+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
+
+RANGED_INTEGERP => RANGED_FIXNUMP
+
+TYPE_RANGED_INTEGERP => TYPE_RANGED_FIXNUMP
+
+make_number => make_fixnum
+
+XINT => XFIXNUM
+
+XFASTINT => XFIXNAT
+
+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;
+}
+
+/* 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 type_of_cursor 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 type_of_cache 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";
+    }
+}
+
+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);
+}
+
+/* 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. */
+static 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, int bottom_vpos,
+                struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+                enum type_of_cursor cursor_type, int wd, bool active_p,
+                bool cursor_gc_p, enum draw_glyph_action action_type)
+{
+  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; 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;
+}
+
+/* EXPORT for RIF:
+   Output LEN glyphs starting at START at the nominal cursor position.
+   Advance the nominal cursor over the text.  UPDATED_ROW is the glyph row
+   being updated, and UPDATED_AREA is the area of that row being updated. */
+void
+mc_x_write_glyphs (struct window *w, struct glyph_matrix *matrix, struct glyph_row *updated_row,
+    struct glyph *start, enum glyph_row_area updated_area, int len,
+    int vpos, int bottom_vpos, struct mc_RGB lsl, enum mc_flavor glyph_flavor,
+    enum type_of_cursor cursor_type, int wd, bool active_p, bool cursor_gc_p)
+{
+  block_input ();
+  int hpos = start - updated_row->glyphs[updated_area];
+  int x = mc_draw_glyphs (w, matrix, updated_row, w->output_cursor.x, updated_area,
+                          hpos, hpos + len, DRAW_NORMAL_TEXT, 0, vpos, bottom_vpos,
+                          lsl, glyph_flavor, cursor_type, wd, active_p, cursor_gc_p,
+                          MC_DRAW_GLYPH);
+  unblock_input ();
+  /* Advance the output cursor. */
+  w->output_cursor.hpos += len;
+  w->output_cursor.x = x;
+}
+
+/* EXPORT:
+   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 type_of_cursor cursor_type, int wd, bool active_p,
+                      bool cursor_gc_p)
+{
+  struct glyph_row *bottom_row = MATRIX_BOTTOM_TEXT_ROW (matrix, w);
+  int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, matrix);
+/*
+      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 ();
+  mc_draw_glyphs (w, matrix, row, x, TEXT_AREA, hpos, hpos + 1, hl, 0,
+                  vpos, bottom_vpos, lsl, glyph_flavor, cursor_type, wd, active_p,
+                  cursor_gc_p, MC_DRAW_GLYPH);
+  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 type_of_cursor 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_row *bottom_row = MATRIX_BOTTOM_TEXT_ROW (matrix, w);
+  int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, matrix);
+/*
+      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 ();
+  mc_draw_glyphs (w, matrix, row, x, TEXT_AREA, hpos, hpos + 1, hl, 0,
+                  vpos, bottom_vpos, lsl, glyph_flavor, cursor_type, wd, active_p,
+                  cursor_gc_p, MC_ERASE_GLYPH);
+  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 type_of_cursor 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-face"), true)
+        : (active_p)
+          ? lookup_named_face (w, f, intern ("+-overlay-arrow-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-face '+-fringe-right-arrow '+-overlay-arrow-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-face"), true)
+          : (active_p)
+            ? lookup_named_face (w, f, intern ("+-overlay-arrow-hscl-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-face '+-fringe-right-arrow '+-overlay-arrow-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-vertical-bar-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 ("+-vertical-bar-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)
+{
+  if (glyph->type == CHAR_GLYPH
+      || glyph->type == GLYPHLESS_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        (glyph->type == CHAR_GLYPH
+         ? 'C'
+         : 'G'),
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        glyph->u.ch,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        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 %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'S',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        0u,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        "\\S");
+    }
+  else if (glyph->type == IMAGE_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'I',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.img_id,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+    }
+  else if (glyph->type == COMPOSITE_GLYPH)
+    {
+      fprintf (stderr,
+        " %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        '+',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+            ? 'B'
+          : (STRINGP (glyph->object)
+            ? 'S'
+          : (NILP (glyph->object)
+            ? '0'
+          : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.cmp.id);
+      fprintf (stderr, " %4d %1.1d%1.1d",
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p);
+      if (glyph->u.cmp.automatic)
+        fprintf (stderr, " %5d %4d  %3d  %3d %s . [%d-%d]\n",
+                         glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+                         glyph->slice.cmp.from, glyph->slice.cmp.to);
+        else
+        fprintf (stderr, "\n");
+    }
+  else if (glyph->type == XWIDGET_GLYPH)
+    {
+#ifndef HAVE_XWIDGETS
+      eassume (false);
+#else
+      fprintf (stderr,
+        "  %5d/%-5d %5d %4c %6d %c %3d 0x%05x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'X',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+           ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+         : '-')),
+        glyph->pixel_width,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->u.xwidget,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+#endif
+    }
+}
+
+/* Dump the contents of glyph row at VPOS in MATRIX to stderr.
+   GLYPHS 0 means don't show glyph contents.
+   GLYPHS 1 means show glyphs in short form
+   GLYPHS > 1 means show glyphs in long form. */
+void
+mc_dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
+{
+  int relative_x = 0;
+  if (glyphs != 1)
+    {
+      fprintf (stderr, "\nDUMP GLYPH ROW\n");
+      fprintf (stderr, "Row     Start       End Used oE><\\CTZFesm     X    Y    W    H    V    A    P\n");
+      fprintf (stderr, "==============================================================================\n");
+      fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
+%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d  %4d %4d %4d %4d %4d %4d %4d\n",
+         vpos,
+         MATRIX_ROW_START_CHARPOS (row),
+         MATRIX_ROW_END_CHARPOS (row),
+         row->used[TEXT_AREA],
+         row->contains_overlapping_glyphs_p,
+         row->enabled_p,
+         row->truncated_on_left_p,
+         row->truncated_on_right_p,
+         row->continued_p,
+         MATRIX_ROW_CONTINUATION_LINE_P (row),
+         MATRIX_ROW_DISPLAYS_TEXT_P (row),
+         row->ends_at_zv_p,
+         row->fill_line_p,
+         row->ends_in_middle_of_char_p,
+         row->starts_in_middle_of_char_p,
+         row->mouse_face_p,
+         row->x,
+         row->y,
+         row->pixel_width,
+         row->height,
+         row->visible_height,
+         row->ascent,
+         row->phys_ascent);
+      /* The next 3 lines should align to "Start" in the header. */
+      fprintf (stderr, "    %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
+         row->end.overlay_string_index,
+         row->continuation_lines_width);
+      fprintf (stderr, "    %9"pD"d %9"pD"d\n",
+         CHARPOS (row->start.string_pos),
+         CHARPOS (row->end.string_pos));
+      fprintf (stderr, "    %9d %9d\n", row->start.dpvec_index,
+         row->end.dpvec_index);
+    }
+  if (glyphs > 1)
+    {
+      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     X    Y HPOS VPOS ZV C\n");
+    for (; glyph < glyph_end; ++glyph)
+      {
+        mc_dump_glyph (row, glyph, area, relative_x);
+        relative_x += glyph->pixel_width;
+      }
+  }
+    }
+  else if (glyphs == 1)
+    {
+      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;
+  EMACS_INT vpos;
+  if (NILP (row))
+    {
+      int d1, d2, d3, d4, d5, ypos;
+      bool visible_p = pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &ypos);
+      int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+      int voffset = (header_line_height > 0
+                     && ypos > 0)
+                      ? ypos + 1
+                      : ypos;
+      if (visible_p)
+        vpos = voffset;
+        else
+          vpos = 0;
+    }
+    else
+      {
+        CHECK_NUMBER (row);
+        vpos = XFIXNUM (row);
+      }
+  matrix = w->current_matrix;
+  if (vpos >= 0 && vpos < matrix->nrows)
+    mc_dump_glyph_row (MATRIX_ROW (matrix, vpos),
+        vpos,
+        TYPE_RANGED_FIXNUMP (int, glyphs) ? XFIXNUM (glyphs) : 2);
+  return Qnil;
+}
+
+void
+mc_dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
+{
+  int i;
+  for (i = 0; i < matrix->nrows; ++i)
+    mc_dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
+}
+
+DEFUN ("mc-dump-glyph-matrix", Fmc_dump_glyph_matrix,
+       Smc_dump_glyph_matrix, 0, 1, "p",
+       doc: /* Dump the current matrix of the selected window to stderr.
+Shows contents of glyph row structures.  With non-nil
+parameter GLYPHS, dump glyphs as well.  If GLYPHS is 1 show
+glyphs in short form, otherwise show glyphs in long form.
+- Interactively, no argument means show glyphs in short form;
+with numeric argument, its value is passed as the GLYPHS flag.  */)
+  (Lisp_Object glyphs)
+{
+  struct window *w = XWINDOW (selected_window);
+  struct buffer *buffer = XBUFFER (w->contents);
+  fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
+     BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
+  fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
+     w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
+  fprintf (stderr, "=============================================\n");
+  mc_dump_glyph_matrix (w->current_matrix,
+         TYPE_RANGED_FIXNUMP (int, glyphs) ? XFIXNUM (glyphs) : 0);
+  return Qnil;
+}
+
+void
+mc_reset_cache (struct window *w, enum type_of_cache cache_type)
+{
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          if (BUFFERP (w->contents)
+              && NILP (BVAR (XBUFFER (w->contents), mc_conf))
+              && w->mc_elts.used > 1)
+            {
+              /* Decrease the size of the array to a bare minimum. */
+              w->mc_elts.caches = xnrealloc (w->mc_elts.caches, 1, sizeof *w->mc_elts.caches);
+              w->mc_elts.used = 0;
+              w->mc_elts.allocated = 1;
+            }
+            //  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 would remain the same.
+            //  memset (w->mc_elts.caches, 0, w->mc_elts.used * (sizeof *w->mc_elts.caches));
+            //  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_elts.used`, we track current data.
+            else if (BUFFERP (w->contents)
+                     && !NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+              w->mc_elts.used = 0;
+          break;
+        }
+      case CH_CACHE:
+        {
+          if (BUFFERP (w->contents)
+              && NILP (BVAR (XBUFFER (w->contents), crosshairs))
+              && w->ch_elts.used > 1)
+            {
+              /* Decrease the size of the array to a bare minimum. */
+              w->ch_elts.caches = xnrealloc (w->ch_elts.caches, 1, sizeof *w->ch_elts.caches);
+              w->ch_elts.used = 0;
+              w->ch_elts.allocated = 1;
+            }
+            //  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 would remain the same.
+            //  memset (w->ch_elts.caches, 0, w->ch_elts.used * (sizeof *w->ch_elts.caches));
+            //  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->ch_elts.used`, we track current data.
+            else if (BUFFERP (w->contents)
+                     && !NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+              w->ch_elts.used = 0;
+          break;
+        }
+      case FC_CACHE:
+        {
+          if (BUFFERP (w->contents)
+              && NILP (BVAR (XBUFFER (w->contents), fc_visible))
+              && w->fc_elts.used > 1)
+            {
+              /* Decrease the size of the array to a bare minimum. */
+              w->fc_elts.caches = xnrealloc (w->fc_elts.caches, 1, sizeof *w->fc_elts.caches);
+              w->fc_elts.used = 0;
+              w->fc_elts.allocated = 1;
+            }
+            //  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 would remain the same.
+            //  memset (w->fc_elts.caches, 0, w->fc_elts.used * (sizeof *w->fc_elts.caches));
+            //  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->fc_elts.used`, we track current data.
+            else if (BUFFERP (w->contents)
+                     && !NILP (BVAR (XBUFFER (w->contents), fc_visible)))
+              w->fc_elts.used = 0;
+          break;
+        }
+    }
+}
+
+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 type_of_cursor 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 type_of_cache cache_type)
+{
+  if (glyph != NULL
+      && glyph->u.ch == 95
+      && cursor_type == MC_HBAR)
+    {
+      struct frame *f = XFRAME (w->frame);
+      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];
+      mc_xw_color_values (w, special_char_fg_color, &foreground);
+    }
+  if (mc_stderr_p)
+    {
+      fprintf (stderr, "\nmc_helper (%s):\n\
+  x (%d) | fx (%d) | y (%d) | fy (%d) | hpos (%d) | vpos (%d) | h (%d)\n\
+  cursor_type (%s) | cursor_width (%d) | active_p (%s)\n\
+  flavor (%s) | FG-RGB (%f/%f/%f) | BG-RGB (%f/%f/%f)\n",
+      mc_window (w),
+      x, fx, y, fy, hpos, vpos, h,
+      mc_cursor_type_to_string (cursor_type),
+      cursor_width,
+      (active_p ? "true" : "false"),
+      mc_flavor_to_string (glyph_flavor),
+      foreground.red, foreground.green, foreground.blue, background.red, background.green, background.blue);
+    }
+  bool remove_p = false;
+  if (draw_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);
+  struct multiple_cursors_cache foo_elts;
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          /* Do not continue to the last section that populates the cache with
+          cursor data, as that will cause a SIGSEGV (segmentation fault). */
+          return;
+        }
+      case MC_CACHE:
+        {
+          ++w->mc_elts.used;
+          if (w->mc_elts.allocated < w->mc_elts.used)
+            {
+              int old_alloc = w->mc_elts.allocated;
+              int new_elts = w->mc_elts.used - w->mc_elts.allocated;
+              w->mc_elts.caches = xpalloc (w->mc_elts.caches, &w->mc_elts.allocated,
+                                           new_elts, INT_MAX, sizeof *w->mc_elts.caches);
+              memset (w->mc_elts.caches + old_alloc, 0,
+                       (w->mc_elts.allocated - old_alloc) * sizeof *w->mc_elts.caches);
+            }
+          foo_elts.caches = w->mc_elts.caches;
+          foo_elts.allocated = w->mc_elts.allocated;
+          foo_elts.used = w->mc_elts.used;
+          break;
+        }
+      case CH_CACHE:
+        {
+          ++w->ch_elts.used;
+          if (w->ch_elts.allocated < w->ch_elts.used)
+            {
+              int old_alloc = w->ch_elts.allocated;
+              int new_elts = w->ch_elts.used - w->ch_elts.allocated;
+              w->ch_elts.caches = xpalloc (w->ch_elts.caches, &w->ch_elts.allocated,
+                                           new_elts, INT_MAX, sizeof *w->ch_elts.caches);
+              memset (w->ch_elts.caches + old_alloc, 0,
+                       (w->ch_elts.allocated - old_alloc) * sizeof *w->ch_elts.caches);
+            }
+          foo_elts.caches = w->ch_elts.caches;
+          foo_elts.allocated = w->ch_elts.allocated;
+          foo_elts.used = w->ch_elts.used;
+          break;
+        }
+      case FC_CACHE:
+        {
+          ++w->fc_elts.used;
+          if (w->fc_elts.allocated < w->fc_elts.used)
+            {
+              int old_alloc = w->fc_elts.allocated;
+              int new_elts = w->fc_elts.used - w->fc_elts.allocated;
+              w->fc_elts.caches = xpalloc (w->fc_elts.caches, &w->fc_elts.allocated,
+                                           new_elts, INT_MAX, sizeof *w->fc_elts.caches);
+              memset (w->fc_elts.caches + old_alloc, 0,
+                       (w->fc_elts.allocated - old_alloc) * sizeof *w->fc_elts.caches);
+            }
+          foo_elts.caches = w->fc_elts.caches;
+          foo_elts.allocated = w->fc_elts.allocated;
+          foo_elts.used = w->fc_elts.used;
+          break;
+        }
+    }
+  int nth = foo_elts.used - 1;
+  foo_elts.caches[nth].x = x;
+  foo_elts.caches[nth].fx = fx;
+  foo_elts.caches[nth].y = y;
+  foo_elts.caches[nth].fy = fy;
+  foo_elts.caches[nth].hpos = hpos;
+  foo_elts.caches[nth].vpos = vpos;
+  foo_elts.caches[nth].wd = wd;
+  foo_elts.caches[nth].h = h;
+  foo_elts.caches[nth].cursor_type = cursor_type;
+  foo_elts.caches[nth].cursor_width = cursor_width;
+  foo_elts.caches[nth].foreground.red = foreground.red;
+  foo_elts.caches[nth].foreground.green = foreground.green;
+  foo_elts.caches[nth].foreground.blue = foreground.blue;
+  foo_elts.caches[nth].background.red = background.red;
+  foo_elts.caches[nth].background.green = background.green;
+  foo_elts.caches[nth].background.blue = background.blue;
+  foo_elts.caches[nth].active_p = active_p;
+  foo_elts.caches[nth].glyph_flavor = glyph_flavor;
+  foo_elts.caches[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 type_of_cursor 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 type_of_cursor cursor_type, int cursor_width,
+           struct glyph_matrix *cursor_matrix, int fc_x, struct mc_RGB foreground,
+           bool active_p, enum type_of_action action_type, bool draw_p,
+           enum type_of_cache 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, fc_x);
+  bool 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 == glyph->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 %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        (glyph->type == CHAR_GLYPH
+         ? 'C'
+         : 'G'),
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+              glyph->pixel_width,
+        glyph->u.ch,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        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,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                   active_p, MC_GLYPH, draw_p, cache_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, active_p, MC_GLYPHLESS, draw_p,
+                     cache_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
+                                    : (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,
+                 active_p, glyph_flavor, draw_p, cache_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
+                    && fc_x >= row->pixel_width)
+                     ? MC_GLYPHLESS
+                   : (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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                        END:  CHAR_GLYPH | GLYPHLESS_GLYPH                   */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                             BEGIN:  STRETCH_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == STRETCH_GLYPH)
+  {
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %s\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'S',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        0u,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        "\\S");
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  STRETCH_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                   active_p, MC_GLYPH, draw_p, cache_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, active_p, MC_GLYPHLESS, draw_p,
+                     cache_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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           FILL_COLUMN:  STRETCH_GLYPH                       */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      if (row->fill_line_p
+          && glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+          && 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
+                 && 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, fc_x, fc_fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                               END:  STRETCH_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                              BEGIN:  IMAGE_GLYPH                            */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == IMAGE_GLYPH)
+  {
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'I',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : (NILP (glyph->object)
+               ? '0'
+               : '-'))),
+        glyph->pixel_width,
+        (unsigned int) glyph->u.img_id,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                         MULTIPLE_CURSORS:  IMAGE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      cursor_type = MC_HOLLOW_BOX;
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                   active_p, MC_GLYPH, draw_p, cache_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,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                 active_p, MC_GLYPH, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                                END:  IMAGE_GLYPH                            */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                            BEGIN:  COMPOSITE_GLYPH                          */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == COMPOSITE_GLYPH)
+  {
+    if (mc_stderr_p)
+      {
+        fprintf (stderr,
+          "\n %5"pD"d/%-5d %5d %c %9"pD"d %c %3d 0x%06x",
+          glyph - row->glyphs[TEXT_AREA],
+          ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+          relative_x,
+          '+',
+          glyph->charpos,
+          (BUFFERP (glyph->object)
+           ? 'B'
+           : (STRINGP (glyph->object)
+              ? 'S'
+              : (NILP (glyph->object)
+                 ? '0'
+                 : '-'))),
+          glyph->pixel_width,
+          (unsigned int) glyph->u.cmp.id);
+        fprintf (stderr, " %4d %1.1d%1.1d",
+          glyph->face_id,
+          glyph->left_box_line_p,
+          glyph->right_box_line_p);
+      if (glyph->u.cmp.automatic)
+        fprintf (stderr, " %5d %4d  %3d  %3d %s . [%d-%d]\n",
+                         glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+                         glyph->slice.cmp.from, glyph->slice.cmp.to);
+        else
+          fprintf (stderr, "\n");
+      }
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                       MULTIPLE_CURSORS:  COMPOSITE_GLYPH                    */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                   active_p, MC_GLYPH, draw_p, cache_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,
+                         active_p, MC_GLYPHLESS, draw_p, cache_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
+                                    : (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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                          FILL_COLUMN:  COMPOSITE_GLYPH                      */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      enum mc_flavor glyph_flavor = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fc_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+  }
+  }
+/* --------------------------------------------------------------------------- */
+/*                              END:  COMPOSITE_GLYPH                          */
+/* --------------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------- */
+/*                             BEGIN:  XWIDGET_GLYPH                           */
+/* --------------------------------------------------------------------------- */
+  else if (glyph->type == XWIDGET_GLYPH)
+  {
+#ifndef HAVE_XWIDGETS
+    eassume (false);
+#else
+    if (mc_stderr_p)
+      fprintf (stderr,
+        "\n  %5d/%-5d %5d %4c %6d %c %3d 0x%05x %4d %1.1d%1.1d %5d %4d  %3d  %3d %s %c\n",
+        glyph - row->glyphs[TEXT_AREA],
+        ((row->used[area] == 0) ? 0 : row->used[area] - 1),
+        relative_x,
+        'X',
+        glyph->charpos,
+        (BUFFERP (glyph->object)
+         ? 'B'
+         : (STRINGP (glyph->object)
+            ? 'S'
+            : '-')),
+        glyph->pixel_width,
+        glyph->face_id,
+        glyph->left_box_line_p,
+        glyph->right_box_line_p,
+        glyph->u.xwidget,
+        glyph->x, glyph->y, glyph->hpos, glyph->vpos, glyph->zv_p ? "ZV" : "--",
+        '.');
+#endif
+  switch (action_type)
+  {
+/* --------------------------------------------------------------------------- */
+/*                        MULTIPLE_CURSORS:  XWIDGET_GLYPH                     */
+/* --------------------------------------------------------------------------- */
+    case MULTIPLE_CURSORS:
+    {
+      mc_helper (w, matrix, row, glyph, relative_x, fx, y, fy, hpos, vpos,
+                 wd, h, cursor_type, cursor_width, foreground, background,
+                 active_p, MC_GLYPH, draw_p, cache_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,
+                   active_p, MC_GLYPH, draw_p, cache_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,
+                         active_p, MC_GLYPHLESS, draw_p, cache_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
+                                    : (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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      break;
+    }
+/* --------------------------------------------------------------------------- */
+/*                           FILL_COLUMN:  XWIDGET_GLYPH                       */
+/* --------------------------------------------------------------------------- */
+    case FILL_COLUMN:
+    {
+      enum mc_flavor glyph_flavor = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1
+                      && fc_x > relative_x)
+                     ? MC_GLYPHLESS
+                   : (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,
+                 active_p, glyph_flavor, draw_p, cache_type);
+      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,
+             int bottom_vpos, bool active_p, struct glyph_matrix *cursor_matrix,
+             int fc_x, struct mc_RGB ch_foreground, struct mc_RGB fc_foreground,
+             bool draw_p)
+{
+  //  clock_t clock_start = clock();
+  /* NT Emacs crashes on startup without a `BUFFERP' check in `update_window'. */
+  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;
+  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 (%s):  vpos (%d) | hpos (%d) | len (%d)\n",
+                     mc_window (w), vpos, hpos_start, hpos_length);
+  Lisp_Object window;
+  XSETWINDOW (window, w);
+  struct frame *f = XFRAME (w->frame);
+  Lisp_Object buf = w->contents;
+  CHECK_BUFFER (buf);
+  struct buffer *b = XBUFFER (buf);
+  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);
+  //  bool cg_p = cursor_glyph == NULL;
+  //  bool cr_p = cursor_row != NULL;
+  //  bool ch_cru = w->cursor.hpos == cursor_row->used[TEXT_AREA];
+  //  bool crewwl_p = !cursor_row->exact_window_width_line_p;
+  //  bool cx_taw_p = w->cursor.x >= text_area_width;
+  //  bool cx_crpw_p = w->cursor.x >= cursor_row->pixel_width;
+  //  fprintf (stderr, "vpos (%d) | hpos (%d/%d) | cursor.x (%d) | taw (%d) | used (%d) | rt_p (%d)\n\
+  //    cg_p (%d), cr_p (%d), ch_cru (%d), crewwl_p (%d), cx_taw_p (%d), cx_crpw_p (%d)\n",
+  //    vpos, hpos_start, hpos_length, w->cursor.x, text_area_width, row->used[TEXT_AREA], row->truncated_on_right_p,
+  //    cg_p, cr_p, ch_cru, crewwl_p, cx_taw_p, cx_crpw_p);
+/* ******************************************************************************
+                          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 type_of_cursor 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;
+  enum face_id cursor_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+  struct face *cursor_face = FACE_FROM_ID (f, cursor_face_id);
+  Lisp_Object cursor_color = cursor_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB cursor_fg;
+  mc_xw_color_values (w, cursor_color, &cursor_fg);
+  /* FIXME:  This creates two MC_GLYPH at the same location and needs to be
+  reduced to just one MC_GLYPH, one vertical bar, and one horizontal bar.  The
+  problem with this is that the letter at point gets written twice and will be
+  just a little thicker than as would normally be the case. */
+  bool fill_column_trumps_p = (!NILP (BVAR (b, ch_vertical_ruler))
+                               && !NILP (BVAR (XBUFFER (w->contents), fc_visible))
+                               && w->cursor.x == fc_x
+                               && !cursor_at_fringe_p
+                               && !cursor_beyond_fringe_p);
+  /* FIXME:  Devise a system so that this only happens once per row when
+  `hpos_length` is less than the entire row. */
+  if (vpos == w->cursor.vpos
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && !NILP (BVAR (XBUFFER (w->contents), ch_horizontal_ruler)))
+    {
+      /* fringe bitmaps use face_id to set the foreground color.  The overlay-arrow
+      is presently the only situation where the `active_p` and `minimal_p` are
+      used to determine the applicable face_id. */
+      struct mc_RGB lsl_fg = {.red = -1.0,
+                              .green = -1.0,
+                              .blue = -1.0};
+      mc_helper (w, matrix, row, cursor_glyph, w->cursor.x, -1, w->cursor.y, -1,
+                 w->cursor.hpos, w->cursor.vpos, -1, -1, MC_LEFT_FRINGE_BITMAP, -1,
+                 lsl_fg, cursor_bg, active_p, MC_OVERLAY_ARROW_BITMAP, draw_p,
+                 CH_CACHE);
+    }
+  if (cursor_at_fringe_p
+      && vpos == w->cursor.vpos
+      && w->cursor.hpos >= hpos_start
+      && w->cursor.hpos == hpos_start + hpos_length
+      && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+      && !NILP (BVAR (XBUFFER (w->contents), ch_horizontal_ruler)))
+    {
+      enum mc_flavor glyph_flavor = MC_HOLLOW_RECTANGLE;
+      mc_helper (w, matrix, row, cursor_glyph, 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, active_p, glyph_flavor, draw_p, CH_CACHE);
+    }
+  /* 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 (XBUFFER (w->contents), crosshairs))
+           && !NILP (BVAR (XBUFFER (w->contents), ch_horizontal_ruler)))
+    {
+      enum mc_flavor glyph_flavor = MC_REVERSED_HOLLOW_RECTANGLE_RIGHT_ARROW;
+      mc_helper (w, matrix, row, cursor_glyph, 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, active_p, glyph_flavor, draw_p, CH_CACHE);
+    }
+  /* 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, active_p, MC_GLYPHLESS,
+                 draw_p, NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                         ? CH_CACHE
+                         : MC_CACHE);
+      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, active_p, MC_GLYPH, draw_p,
+                 NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                 ? CH_CACHE
+                 : MC_CACHE);
+    }
+  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, active_p,
+                 MC_GLYPH, draw_p, NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                                   ? CH_CACHE
+                                   : MC_CACHE);
+    }
+  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,
+                     active_p, MC_GLYPH, draw_p,
+                     NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                     ? CH_CACHE
+                     : MC_CACHE);
+        }
+      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, active_p,
+                 MC_GLYPH, draw_p, NILP (BVAR (XBUFFER (w->contents), mc_conf))
+                                   ? CH_CACHE
+                                   : MC_CACHE);
+    }
+/* ******************************************************************************
+                          DRAW AND RECORD FAKE CURSORS
+****************************************************************************** */
+  if (hpos_length == 1)
+    {
+      if (!NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+        {
+          /* 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;
+          bool skip_p = (previous_glyph != NULL
+                         && previous_glyph->charpos == MATRIX_ROW_END_CHARPOS (row) - 1);
+          int posint = (start - row->glyphs[TEXT_AREA] == row->used[TEXT_AREA] - 1)
+                       ? MATRIX_ROW_END_CHARPOS (row) - 1
+                       : start->charpos;
+          Lisp_Object specs = mc_assoc (make_fixnum (posint), BVAR (XBUFFER (w->contents), mc_conf));
+          if (((header_line_format > 0 && vpos > 0)
+               || header_line_format == 0)
+              && !NILP (specs)
+              && start->y <= window_text_bottom_y (w)
+              && !skip_p
+              && !start->zv_p)
+            {
+              Lisp_Object lisp_type = mc_nth (1, specs);
+              enum type_of_cursor 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 foreground;
+              if (STRINGP (mc_foreground))
+                mc_xw_color_values (w, mc_foreground, &foreground);
+                else if (VECTORP (mc_foreground))
+                  {
+                    double red_fg = XFLOAT_DATA (AREF (mc_foreground, 0));
+                    double green_fg = XFLOAT_DATA (AREF (mc_foreground, 1));
+                    double blue_fg = XFLOAT_DATA (AREF (mc_foreground, 2));
+                    foreground.red = red_fg;
+                    foreground.green = green_fg;
+                    foreground.blue = blue_fg;
+                  }
+                  else if (NILP (mc_foreground))
+                    {
+                      foreground.red = ch_foreground.red;
+                      foreground.green = ch_foreground.green;
+                      foreground.blue = ch_foreground.blue;
+                    }
+              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, fc_x, foreground, active_p,
+                         MULTIPLE_CURSORS, draw_p, MC_CACHE);
+            }
+        }
+      if (!NILP (BVAR (XBUFFER (w->contents), fc_visible))
+          && fc_x <= text_area_width
+          && fc_x >= w->mc.lnum_pixel_width)
+        {
+          int x_limit = x + start->pixel_width;
+          bool real_fake_cursor_p = (w->cursor.x == fc_x
+                                     && w->cursor.y == start->y
+                                     && w->cursor.hpos == start - row->glyphs[TEXT_AREA]
+                                     && w->cursor.vpos == vpos);
+          if (x + start->pixel_width <= text_area_width
+              && ((header_line_format > 0 && vpos > 0)
+                  || header_line_format == 0)
+              && ((fc_x >= x
+                   && fc_x < x + start->pixel_width)
+                  || start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1)
+              && start->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, fc_x, fc_foreground, active_p, FILL_COLUMN,
+                       draw_p, FC_CACHE);
+        }
+      if (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          && !NILP (BVAR (b, ch_horizontal_ruler))
+          && vpos == w->cursor.vpos)
+        {
+          int x_limit = (start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1)
+                        ? text_area_width
+                        : x + start->pixel_width;
+          /* 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, fc_x, ch_foreground, active_p,
+                     HORIZONTAL_RULER, draw_p, CH_CACHE);
+        }
+      if (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+          && !NILP (BVAR (b, ch_vertical_ruler))
+          && !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 == start->y
+                                     && w->cursor.vpos == vpos);
+          if (((header_line_format > 0 && vpos > 0)
+               || header_line_format == 0)
+              && ((w->cursor.x >= x
+                   && w->cursor.x < x + start->pixel_width)
+                  || start == row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1)
+              && start->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, fc_x, ch_foreground, active_p,
+                       VERTICAL_RULER, draw_p, 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
+                    && fc_x < relative_x
+                    && w->cursor.x < relative_x
+                    && NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+                  break;
+                if (!NILP (BVAR (XBUFFER (w->contents), mc_conf)))
+                  {
+                    /* 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;
+                    bool skip_p = (previous_glyph != NULL
+                                   && previous_glyph->charpos == MATRIX_ROW_END_CHARPOS (row) - 1)
+                                    ? 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 = (glyph - row->glyphs[TEXT_AREA] == row->used[area] - 1)
+                                 ? MATRIX_ROW_END_CHARPOS (row) - 1
+                                 : glyph->charpos;
+                    Lisp_Object specs = mc_assoc (make_fixnum (posint), BVAR (XBUFFER (w->contents), mc_conf));
+                    if (((header_line_format > 0 && vpos > 0)
+                         || header_line_format == 0)
+                        && !NILP (specs)
+                        && glyph->y <= window_text_bottom_y (w)
+                        && !skip_p
+                        && !glyph->zv_p)
+                      {
+                        Lisp_Object lisp_type = mc_nth (1, specs);
+                        enum type_of_cursor 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 foreground;
+                        if (STRINGP (mc_foreground))
+                          mc_xw_color_values (w, mc_foreground, &foreground);
+                          else if (VECTORP (mc_foreground))
+                            {
+                              double red_fg = XFLOAT_DATA (AREF (mc_foreground, 0));
+                              double green_fg = XFLOAT_DATA (AREF (mc_foreground, 1));
+                              double blue_fg = XFLOAT_DATA (AREF (mc_foreground, 2));
+                              foreground.red = red_fg;
+                              foreground.green = green_fg;
+                              foreground.blue = blue_fg;
+                            }
+                            else if (NILP (mc_foreground))
+                            {
+                              foreground.red = ch_foreground.red;
+                              foreground.green = ch_foreground.green;
+                              foreground.blue = ch_foreground.blue;
+                            }
+                        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,
+                                   fc_x, foreground, active_p, MULTIPLE_CURSORS,
+                                   draw_p, MC_CACHE);
+                      }
+                  }
+                if (!NILP (BVAR (XBUFFER (w->contents), fc_visible))
+                    && fc_x <= text_area_width
+                    && fc_x >= w->mc.lnum_pixel_width)
+                  {
+                    int x_limit = window_box_width (w, TEXT_AREA);
+                    bool real_fake_cursor_p = (w->cursor.x == fc_x
+                                               && w->cursor.y == glyph->y
+                                               && w->cursor.hpos == glyph - row->glyphs[TEXT_AREA]
+                                               && w->cursor.vpos == vpos);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    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
+                             && fc_x >= relative_x
+                             && fc_x < relative_x + glyph->pixel_width)
+                            || (glyph == glyph_end - 1
+                                && fc_x >= relative_x))
+                        && glyph->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,
+                                 fc_x, fc_foreground, active_p, FILL_COLUMN,
+                                 draw_p, FC_CACHE);
+                  }
+                if (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                    && !NILP (BVAR (b, ch_horizontal_ruler))
+                    && vpos == w->cursor.vpos)
+                  {
+                    int x_limit = window_box_width (w, TEXT_AREA);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    /* 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,
+                                 fc_x, ch_foreground, active_p, HORIZONTAL_RULER,
+                                 draw_p, CH_CACHE);
+                  }
+                if (!NILP (BVAR (XBUFFER (w->contents), crosshairs))
+                    && !NILP (BVAR (b, ch_vertical_ruler))
+                    && !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 == glyph->y
+                                               && w->cursor.vpos == vpos);
+                    int hpos = glyph - row->glyphs[TEXT_AREA];
+                    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))
+                        && glyph->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,
+                                 fc_x, ch_foreground, active_p, VERTICAL_RULER,
+                                 draw_p, 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);
+}
+
+void
+mc_redraw_helper (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                  enum type_of_cache cache_type, int start_hpos, int end_hpos)
+{
+  int row_vpos = MATRIX_ROW_VPOS (row, matrix);
+  struct multiple_cursors_cache foo_elts;
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          foo_elts.caches = w->mc_elts.caches;
+          foo_elts.allocated = w->mc_elts.allocated;
+          foo_elts.used = w->mc_elts.used;
+          break;
+        }
+      case CH_CACHE:
+        {
+          foo_elts.caches = w->ch_elts.caches;
+          foo_elts.allocated = w->ch_elts.allocated;
+          foo_elts.used = w->ch_elts.used;
+          break;
+        }
+      case FC_CACHE:
+        {
+          foo_elts.caches = w->fc_elts.caches;
+          foo_elts.allocated = w->fc_elts.allocated;
+          foo_elts.used = w->fc_elts.used;
+          break;
+        }
+    }
+  /* STRETCH_GLYPH may contain more than one fake cursor at the same HPOS. */
+  for (int elt = 0; elt < foo_elts.used; ++elt)
+    {
+      int x = foo_elts.caches[elt].x;
+      int fx = foo_elts.caches[elt].fx;
+      int y = foo_elts.caches[elt].y;
+      int fy = foo_elts.caches[elt].fy;
+      int hpos = foo_elts.caches[elt].hpos;
+      int vpos = foo_elts.caches[elt].vpos;
+      int wd = foo_elts.caches[elt].wd;
+      int h = foo_elts.caches[elt].h;
+      enum type_of_cursor cursor_type = foo_elts.caches[elt].cursor_type;
+      int cursor_width = foo_elts.caches[elt].cursor_width;
+      struct mc_RGB lsl_fg = {.red = foo_elts.caches[elt].foreground.red,
+                              .green = foo_elts.caches[elt].foreground.green,
+                              .blue = foo_elts.caches[elt].foreground.blue};
+      struct mc_RGB lsl_bg = {.red = foo_elts.caches[elt].background.red,
+                              .green = foo_elts.caches[elt].background.green,
+                              .blue = foo_elts.caches[elt].background.blue};
+      bool active_p = foo_elts.caches[elt].active_p;
+      enum mc_flavor glyph_flavor = foo_elts.caches[elt].glyph_flavor;
+      bool enabled_p = foo_elts.caches[elt].enabled_p;
+      if (vpos == row_vpos
+          && ((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);
+        }
+    }
+}
+
+void
+mc_redraw_row (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+               int start_x, int start_hpos, int end_hpos, bool clear_eol_p,
+               enum draw_glyphs_face hl)
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  int vpos = MATRIX_ROW_VPOS (row, matrix);
+  //  TRACE ((stderr, "mc_redraw_row (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+  //                  vpos, start_x, start_hpos, end_hpos));
+  struct glyph_row *bottom_row = MATRIX_BOTTOM_TEXT_ROW (matrix, w);
+  int bottom_vpos = MATRIX_ROW_VPOS (bottom_row, matrix);
+  struct mc_RGB lsl = {.red = -1.0, .green = -1.0, .blue = -1.0};
+  enum mc_flavor glyph_flavor = NO_FLAVOR;
+  enum type_of_cursor 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;
+  //  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, bottom_vpos, lsl, glyph_flavor,
+                        cursor_type, wd, active_p, cursor_gc_p, MC_DRAW_GLYPH);
+  //  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'.  We are mimicking
+  the behavior of `mc_x_write_glyphs' here by moving the output cursor.  We could
+  have called `rif->mc_scribe_glyphs' instead of just plain old `mc_draw_glyphs'. */
+  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();
+  mc_redraw_helper (w, matrix, row, MC_CACHE, start_hpos, end_hpos);
+  mc_redraw_helper (w, matrix, row, CH_CACHE, start_hpos, end_hpos);
+  mc_redraw_helper (w, matrix, row, FC_CACHE, start_hpos, end_hpos);
+  //  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_helper (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row,
+                 enum type_of_cache cache_type)
+{
+  int row_vpos = MATRIX_ROW_VPOS (row, matrix);
+  //  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), row_vpos);
+  struct multiple_cursors_cache foo_elts;
+  switch (cache_type)
+    {
+      case NO_CACHE:
+        {
+          break;
+        }
+      case MC_CACHE:
+        {
+          foo_elts.caches = w->mc_elts.caches;
+          foo_elts.allocated = w->mc_elts.allocated;
+          foo_elts.used = w->mc_elts.used;
+          break;
+        }
+      case CH_CACHE:
+        {
+          foo_elts.caches = w->ch_elts.caches;
+          foo_elts.allocated = w->ch_elts.allocated;
+          foo_elts.used = w->ch_elts.used;
+          break;
+        }
+      case FC_CACHE:
+        {
+          foo_elts.caches = w->fc_elts.caches;
+          foo_elts.allocated = w->fc_elts.allocated;
+          foo_elts.used = w->fc_elts.used;
+          break;
+        }
+    }
+  for (int elt = 0; elt < foo_elts.used; ++elt)
+    {
+      int x = foo_elts.caches[elt].x;
+      int fx = foo_elts.caches[elt].fx;
+      int y = foo_elts.caches[elt].y;
+      int fy = foo_elts.caches[elt].fy;
+      int hpos = foo_elts.caches[elt].hpos;
+      int vpos = foo_elts.caches[elt].vpos;
+      int wd = foo_elts.caches[elt].wd;
+      int h = foo_elts.caches[elt].h;
+      enum type_of_cursor cursor_type = foo_elts.caches[elt].cursor_type;
+      int cursor_width = foo_elts.caches[elt].cursor_width;
+      struct mc_RGB lsl_fg = {.red = foo_elts.caches[elt].foreground.red,
+                              .green = foo_elts.caches[elt].foreground.green,
+                              .blue = foo_elts.caches[elt].foreground.blue};
+      struct mc_RGB lsl_bg = {.red = foo_elts.caches[elt].background.red,
+                              .green = foo_elts.caches[elt].background.green,
+                              .blue = foo_elts.caches[elt].background.blue};
+      bool active_p = foo_elts.caches[elt].active_p;
+      enum mc_flavor glyph_flavor = foo_elts.caches[elt].glyph_flavor;
+      bool enabled_p = foo_elts.caches[elt].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 == row_vpos
+          && glyph_flavor == MC_GLYPH
+          && enabled_p)
+        {
+          mc_erase_cursor (w, matrix, row, x, y, hpos, vpos, glyph_flavor, cursor_type, wd);
+          foo_elts.caches[elt].enabled_p = false;
+        }
+        else if (vpos == row_vpos
+                 && 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);
+            foo_elts.caches[elt].enabled_p = false;
+          }
+    }
+}
+
+void
+mc_erase_row (struct window *w, struct glyph_matrix *matrix, struct glyph_row *row)
+{
+  int vpos = MATRIX_ROW_VPOS (row, matrix);
+  if (trace_redisplay_p)
+    fprintf (stderr, "mc_erase_row (%s):  vpos (%d)\n", mc_window (w), vpos);
+  mc_erase_helper (w, matrix, row, MC_CACHE);
+  mc_erase_helper (w, matrix, row, CH_CACHE);
+  mc_erase_helper (w, matrix, row, FC_CACHE);
+}
+
+void
+mc_set_essentials (struct window *w, bool active_p, struct mc_RGB *ch_foreground,
+                   struct mc_RGB *fc_foreground, int *fc_x)
+{
+  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);
+  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 fc_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);
+    }
+  *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_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), fc_inactive_windows))
+     && NILP (BVAR (XBUFFER (w->contents), crosshairs)))
+      ? lookup_named_face (w, f, intern ("fc-inactive-face"), true)
+    : (!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 == *fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-inactive-face"), true)
+    : (active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x == *fc_x)
+      ? lookup_named_face (w, f, intern ("fc-opoint-face"), true)
+    : (!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 != *fc_x)
+      ? lookup_named_face (w, f, intern ("fc-inactive-face"), true)
+    : (active_p
+       && !NILP (BVAR (XBUFFER (w->contents), crosshairs))
+       && !NILP (BVAR (b, ch_vertical_ruler))
+       && w->cursor.x != *fc_x)
+      ? lookup_named_face (w, f, intern ("fc-face"), true)
+    : lookup_named_face (w, f, intern ("fc-face"), true);
+  struct face *fill_column_face = FACE_FROM_ID (f, fill_column_face_id);
+  Lisp_Object fill_column_color = fill_column_face->lface[LFACE_FOREGROUND_INDEX];
+  mc_xw_color_values (w, fill_column_color, fc_foreground);
+  enum face_id even_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-even-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-even-numbered-column-face"), true);
+  struct face *even_face = FACE_FROM_ID (f, even_face_id);
+  Lisp_Object even_color = even_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB even_foreground;
+  mc_xw_color_values (w, even_color, &even_foreground);
+  enum face_id odd_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-odd-numbered-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-odd-numbered-column-face"), true);
+  struct face *odd_face = FACE_FROM_ID (f, odd_face_id);
+  Lisp_Object odd_color = odd_face->lface[LFACE_FOREGROUND_INDEX];
+  struct mc_RGB odd_foreground;
+  mc_xw_color_values (w, odd_color, &odd_foreground);
+  enum face_id beyond_fill_face_id =
+    (!active_p
+     && !NILP (BVAR (XBUFFER (w->contents), ch_inactive_windows)))
+    ? lookup_named_face (w, f, intern ("+-beyond-fill-column-inactive-face"), true)
+    : lookup_named_face (w, f, intern ("+-beyond-fill-column-face"), true);
+  struct face *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 (fc_current_col % 2 != 0
+      && !fill_column_p)
+    {
+      ch_foreground->red = odd_foreground.red;
+      ch_foreground->green = odd_foreground.green;
+      ch_foreground->blue = odd_foreground.blue;
+    }
+  /* yellow */
+  if (fc_current_col % 2 == 0
+      && !fill_column_p)
+    {
+      ch_foreground->red = even_foreground.red;
+      ch_foreground->green = even_foreground.green;
+      ch_foreground->blue = even_foreground.blue;
+    }
+  /* red */
+  if (fc_current_col % 2 != 0
+      && fill_column_p
+      && fc_current_col <= fill_col)
+    {
+      ch_foreground->red = odd_foreground.red;
+      ch_foreground->green = odd_foreground.green;
+      ch_foreground->blue = odd_foreground.blue;
+    }
+  /* yellow */
+  if (fc_current_col % 2 == 0
+      && fill_column_p
+      && fc_current_col <= fill_col)
+    {
+      ch_foreground->red = even_foreground.red;
+      ch_foreground->green = even_foreground.green;
+      ch_foreground->blue = even_foreground.blue;
+    }
+  /* green */
+  if (fill_column_p
+      && fc_current_col > fill_col)
+    {
+      ch_foreground->red = beyond_fill_foreground.red;
+      ch_foreground->green = beyond_fill_foreground.green;
+      ch_foreground->blue = beyond_fill_foreground.blue;
+    }
+}
+
+void
+mc_pre_scroll_clean (struct window *w)
+{
+  if (MINI_WINDOW_P (w))
+    return;
+  bool go_one_p = (w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 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):  go_one_p (%s) | go_two_p (%s)\n",
+                     mc_window (w), go_one_p ? "yes" : "no", go_two_p ? "yes" : "no");
+  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 *current_matrix = w->current_matrix;
+  for (int vpos = 0;
+       vpos < current_matrix->nrows
+       && MATRIX_ROW (current_matrix, vpos)->enabled_p
+       && go_one_p;
+       ++vpos)
+    {
+      struct glyph_row *row = MATRIX_ROW (current_matrix, vpos);
+      mc_erase_row (w, current_matrix, row);
+    }
+  if (updating_frame_p)
+    update_end (f);
+  mc_reset_cache (w, MC_CACHE);
+  mc_reset_cache (w, CH_CACHE);
+  mc_reset_cache (w, FC_CACHE);
+}
+
+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 +17489,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 +18444,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 +21857,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 +21887,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 +22195,19 @@ 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.  */
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (trace_redisplay_p)
+    fprintf (stderr, "try_window_reusing_current_matrix [1 of 2] (%s)\n", mc_window (w));
+
+  mc_pre_scroll_clean (w);
+
+/* *************************************************************************** */
+
+
 	  run.current_y = start_row->y;
 	  run.desired_y = it.current_y;
 	  run.height = it.last_visible_y - it.current_y;
@@ -18173,6 +22371,19 @@ try_window_reusing_current_matrix (struct window *w)
 	}
 
       /* Scroll the display.  */
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (trace_redisplay_p)
+    fprintf (stderr, "try_window_reusing_current_matrix [2 of 2] (%s)\n", mc_window (w));
+
+  mc_pre_scroll_clean (w);
+
+/* *************************************************************************** */
+
+
       run.current_y = first_reusable_row->y;
       run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
       run.height = it.last_visible_y - run.current_y;
@@ -19127,6 +23338,19 @@ 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.  */
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if (trace_redisplay_p)
+    fprintf (stderr, "try_window_id (%s)\n", mc_window (w));
+
+  mc_pre_scroll_clean (w);
+
+/* *************************************************************************** */
+
+
   if (dy && run.height)
     {
       update_begin (f);
@@ -20133,6 +24357,17 @@ append_space_for_newline (struct it *it, bool default_face_p)
 	  memset (&it->position, 0, sizeof it->position);
 	  it->object = Qnil;
 	  it->c = it->char_to_display = ' ';
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      if (IT_BYTEPOS (*it) >= ZV_BYTE)
+        it->zv_p = true;
+
+/* *************************************************************************** */
+
+
 	  it->len = 1;
 
 	  /* If the default face was remapped, be sure to use the
@@ -21269,9 +25504,22 @@ maybe_produce_line_number (struct it *it)
       else
 	tem_it.c = tem_it.char_to_display = *p;
       tem_it.len = 1;
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      if (beyond_zv)
+        tem_it.zv_p = true;
+      tem_it.current_y = it->current_y;
+      tem_it.vpos = it->vpos;
       /* Make sure these glyphs will have a "position" of -1.  */
       SET_TEXT_POS (tem_it.position, -1, -1);
       PRODUCE_GLYPHS (&tem_it);
+      tem_it.hpos += 1;
+
+/* *************************************************************************** */
+
 
       /* Stop producing glyphs, and refrain from producing the line
 	 number, if we don't have enough space on this line.  */
@@ -21284,6 +25532,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 +31364,20 @@ append_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       if (it->pixel_width > 0)
@@ -27175,6 +31461,20 @@ append_composite_glyph (struct it *it)
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[it->area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = it->cmp_it.charpos;
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -27383,6 +31683,20 @@ produce_image_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27486,6 +31800,20 @@ produce_xwidget_glyph (struct it *it)
 	}
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
 	  glyph->charpos = CHARPOS (it->position);
 	  glyph->object = it->object;
 	  glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
@@ -27572,6 +31900,20 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
 	    width -= it->first_visible_x - it->current_x;
 	  eassert (width > 0);
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = object;
       /* FIXME: It would be better to use TYPE_MAX here, but
@@ -28026,6 +32368,20 @@ append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
 	    g[1] = *g;
 	  glyph = it->glyph_row->glyphs[area];
 	}
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+      glyph->x = it->current_x;
+      glyph->y = it->current_y;
+      glyph->hpos = it->hpos;
+      glyph->vpos = it->vpos;
+      glyph->zv_p = it->zv_p;
+
+/* *************************************************************************** */
+
+
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       eassert (it->pixel_width <= SHRT_MAX);
@@ -29076,10 +33432,33 @@ x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
 
   /* Write the glyphs.  */
   hpos = start - row->glyphs[updated_area];
+
+
+/* *************************************************************************** */
+/* MULTIPLE-CURSORS */
+
+  if ((w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+      && updated_area == TEXT_AREA)
+    {
+      struct glyph_matrix *matrix = w->current_matrix;
+      int vpos = MATRIX_ROW_VPOS (row, matrix);
+      int start_x = w->output_cursor.x;
+      int start_hpos = hpos;
+      int end_hpos = hpos + len;
+      bool clear_eol_p = false;
+      enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+      TRACE ((stderr, "x_insert_glyphs (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+                      vpos, start_x, start_hpos, end_hpos));
+      mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+    }
+    else
   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 +33884,31 @@ 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 ((w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+            && area == TEXT_AREA)
+          {
+            struct glyph_matrix *matrix = w->current_matrix;
+            int vpos = MATRIX_ROW_VPOS (row, matrix);
+            int start_hpos = start;
+            int end_hpos = i;
+            bool clear_eol_p = false;
+            enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+            TRACE ((stderr, "x_fix_overlapping_area (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+                            vpos, start_x, start_hpos, end_hpos));
+            mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+          }
+          else
 	  draw_glyphs (w, start_x, row, area,
 		       start, i,
 		       DRAW_NORMAL_TEXT, overlaps);
+
+/* *************************************************************************** */
+
+
 	}
       else
 	{
@@ -29758,10 +34159,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 +34182,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 +34203,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 +34308,27 @@ 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 (w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+        {
+          struct glyph_matrix *matrix = w->current_matrix;
+          int vpos = MATRIX_ROW_VPOS (row, matrix);
+          bool clear_eol_p = false;
+          enum draw_glyphs_face hl = draw;
+          TRACE ((stderr, "draw_row_with_mouse_face (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+                          vpos, start_x, start_hpos, end_hpos));
+          mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+        }
+        else
       draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
+
+/* *************************************************************************** */
+
+
       return;
     }
 #endif
@@ -31945,11 +36386,34 @@ 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 (w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+        {
+          struct glyph_matrix *matrix = w->current_matrix;
+          int vpos = MATRIX_ROW_VPOS (row, matrix);
+          int start_x = 0;
+          int start_hpos = 0;
+          int end_hpos = row->used[TEXT_AREA];
+          bool clear_eol_p = false;
+          enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+          TRACE ((stderr, "expose_area (%d):  Write the whole line.\n", vpos));
+          mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+        }
+        else
     /* 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 +36445,34 @@ 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 ((w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+          && area == TEXT_AREA)
+        {
+          struct glyph_matrix *matrix = w->current_matrix;
+          int vpos = MATRIX_ROW_VPOS (row, matrix);
+          start_x = first_x - start_x;
+          int start_hpos = first - row->glyphs[TEXT_AREA];
+          int end_hpos = last - row->glyphs[TEXT_AREA];
+          bool clear_eol_p = false;
+          enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+          TRACE ((stderr, "expose_area (%d):  start_x (%d) | start_hpos (%d) | end_hpos (%d)\n",
+                          vpos, start_x, start_hpos, end_hpos));
+          mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+        }
+        else if (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 +36486,33 @@ 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 (w->mc_elts.used > 0 || w->ch_elts.used > 0 || w->fc_elts.used > 0)
+        {
+          struct glyph_matrix *matrix = w->current_matrix;
+          int vpos = MATRIX_ROW_VPOS (row, matrix);
+          int start_x = 0;
+          int start_hpos = 0;
+          int end_hpos = row->used[TEXT_AREA];
+          bool clear_eol_p = false;
+          enum draw_glyphs_face hl = DRAW_NORMAL_TEXT;
+          TRACE ((stderr, "expose_line (%d):  Write the whole line.\n", vpos));
+          mc_redraw_row (w, matrix, row, start_x, start_hpos, end_hpos, clear_eol_p, hl);
+        }
+        else
     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 +37060,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..953a104 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -132,6 +132,869 @@ 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 type_of_cursor 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 type_of_cursor 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 type_of_cursor 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_beginning = (region_active_p) ? XFIXNUM (Fregion_beginning ()) : -1;
+      ptrdiff_t region_end = (region_active_p) ? XFIXNUM (Fregion_end ()) : -1;
+      ptrdiff_t opoint_pt = (w == XWINDOW (selected_window))
+                            ? PT
+                            : XFIXNUM (Fmarker_position (w->pointm));
+      bool region_in_bounds_p = (region_active_p
+                                 && opoint_pt >= region_beginning
+                                 && opoint_pt < region_end);
+      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
+              && region_in_bounds_p
+              && active_p)
+            {
+              enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+              struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+              enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+              struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+              XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+              XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_face->background);
+            }
+            else if (region_active_p
+                     && !region_in_bounds_p
+                     && active_p)
+              {
+                enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+                XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_out_face->foreground);
+              }
+              else if (!region_active_p && active_p)
+                {
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+                  XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->background);
+                }
+                /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                else if (!active_p)
+                  {
+                    enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                    struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                    XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, 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
+                  && region_in_bounds_p
+                  && active_p)
+                {
+                  enum face_id hollow_active_region_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                  struct face *hollow_active_region_face = FACE_FROM_ID (f, hollow_active_region_face_id);
+                  enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                  struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                  XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+                  XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_face->background);
+                }
+                else if (region_active_p
+                         && !region_in_bounds_p
+                         && active_p)
+                  {
+                    enum face_id hollow_active_region_out_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-region-face"), true);
+                    struct face *hollow_active_region_out_face = FACE_FROM_ID (f, hollow_active_region_out_face_id);
+                    enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                    struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                    XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+                    XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_region_out_face->foreground);
+                  }
+                  else if (!region_active_p && active_p)
+                    {
+                      enum face_id hollow_active_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-face"), true);
+                      struct face *hollow_active_face = FACE_FROM_ID (f, hollow_active_face_id);
+                      XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->foreground);
+                      XSetBackground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, hollow_active_face->background);
+                    }
+                    /* The region is _not_ visible in the inactive window because the overlay window property is used. */
+                    else if (!active_p)
+                      {
+                        enum face_id hollow_inactive_face_id = lookup_named_face (w, f, intern ("+-real-fake-cursor-inactive-face"), true);
+                        struct face *hollow_inactive_face = FACE_FROM_ID (f, hollow_inactive_face_id);
+                        XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, 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 type_of_cursor 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 +1862,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 +2138,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 +13982,21 @@ 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_write_glyphs,
+  mc_x_draw_window_cursor,
+  mc_x_draw_glyph_string,
+
+/* *************************************************************************** */
+
+
     x_frame_parm_handlers,
     x_produce_glyphs,
     x_write_glyphs,
