Function: ediff-setup-windows-multiframe-compare

ediff-setup-windows-multiframe-compare is a byte-compiled function defined in ediff-wind.el.gz.

Signature

(ediff-setup-windows-multiframe-compare BUF-A BUF-B BUF-C CONTROL-BUF)

Source Code

;; Defined in /usr/src/emacs/lisp/vc/ediff-wind.el.gz
;; Window setup for all comparison jobs, including 3way comparisons
(defun ediff-setup-windows-multiframe-compare (buf-A buf-B buf-C control-buf)
  ;; Algorithm:
  ;;    If a buffer is seen in a frame, use that frame for that buffer.
  ;;    If it is not seen, use the current frame.
  ;;    If both buffers are not seen, they share the current frame.  If one
  ;;    of the buffers is not seen, it is placed in the current frame (where
  ;;    ediff started).  If that frame is displaying the other buffer, it is
  ;;    shared between the two buffers.
  ;;    However, if we decide to put both buffers in one frame
  ;;    and the selected frame isn't splittable, we create a new frame and
  ;;    put both buffers there, event if one of this buffers is visible in
  ;;    another frame.

  (let* ((window-min-height 1)
	 (wind-A (ediff-get-visible-buffer-window buf-A))
	 (wind-B (ediff-get-visible-buffer-window buf-B))
	 (wind-C (ediff-get-visible-buffer-window buf-C))
	 (frame-A (if wind-A (window-frame wind-A)))
	 (frame-B (if wind-B (window-frame wind-B)))
	 (frame-C (if wind-C (window-frame wind-C)))
	 (ctl-frame-exists-p (with-current-buffer control-buf
			       (frame-live-p ediff-control-frame)))
	 ;; on wide display, do things in one frame
	 (force-one-frame
	  (with-current-buffer control-buf ediff-wide-display-p))
	 ;; this lets us have local versions of ediff-split-window-function
	 (split-window-function
	  (with-current-buffer control-buf ediff-split-window-function))
	 (three-way-comparison
	  (with-current-buffer control-buf ediff-3way-comparison-job))
	 (use-same-frame (or force-one-frame
			     (eq frame-A frame-B)
			     (not (ediff-window-ok-for-display wind-A))
			     (not (ediff-window-ok-for-display wind-B))
			     (if three-way-comparison
				 (or (eq frame-A frame-C)
				     (eq frame-B frame-C)
				     (not (ediff-window-ok-for-display wind-C))
				     (not (frame-live-p frame-A))
				     (not (frame-live-p frame-B))
				     (not (frame-live-p frame-C))))
			     (and (not (frame-live-p frame-B))
				  (or ctl-frame-exists-p
				      (eq frame-A (selected-frame))))
			     (and (not (frame-live-p frame-A))
				  (or ctl-frame-exists-p
				      (eq frame-B (selected-frame))))))
         (window-combination-resize t)
	 wind-A-start wind-B-start
	 designated-minibuffer-frame)

    (with-current-buffer control-buf
      (setq wind-A-start (ediff-overlay-start
			  (ediff-get-value-according-to-buffer-type
			   'A ediff-narrow-bounds))
	    wind-B-start (ediff-overlay-start
			  (ediff-get-value-according-to-buffer-type
			   'B ediff-narrow-bounds))))

    (if use-same-frame
        (progn
	  (if (and (eq frame-A frame-B) (frame-live-p frame-A))
	      (select-frame frame-A)
	    ;; avoid dedicated and non-splittable windows
	    (ediff-skip-unsuitable-frames))
	  (delete-other-windows)
	  (switch-to-buffer buf-A)
	  (setq wind-A (selected-window))

          (funcall split-window-function)
	  (if (eq (selected-window) wind-A)
	      (other-window 1))
	  (switch-to-buffer buf-B)
	  (setq wind-B (selected-window))

	  (if three-way-comparison
	      (progn
		(funcall split-window-function) ; equally
		(if (memq (selected-window) (list wind-A wind-B))
		    (other-window 1))
		(switch-to-buffer buf-C)
		(setq wind-C (selected-window)))))

      (if (window-live-p wind-A)        ; buf-A on its own
	  (progn
	    ;; buffer buf-A is seen in live wind-A
	    (select-window wind-A)      ; must be displaying buf-A
	    (delete-other-windows)
	    (setq wind-A (selected-window))) ;FIXME: Why?
	;; Buf-A was not set up yet as it wasn't visible,
	;; and use-same-frame = nil
        ;; Skip dedicated or iconified frames.
        ;; Unsplittable frames are taken care of later.
        (ediff-skip-unsuitable-frames 'ok-unsplittable)
	(delete-other-windows)
	(switch-to-buffer buf-A)
	(setq wind-A (selected-window)))

      (if (window-live-p wind-B)        ; buf B on its own
	  (progn
	    ;; buffer buf-B is seen in live wind-B
	    (select-window wind-B)      ; must be displaying buf-B
	    (delete-other-windows)
	    (setq wind-B (selected-window))) ;FIXME: Why?
	;; Buf-B was not set up yet as it wasn't visible,
	;; and use-same-frame = nil
        ;; Skip dedicated or iconified frames.
        ;; Unsplittable frames are taken care of later.
        (ediff-skip-unsuitable-frames 'ok-unsplittable)
	(delete-other-windows)
	(switch-to-buffer buf-B)
	(setq wind-B (selected-window)))

      (if (window-live-p wind-C)        ; buf C on its own
	  (progn
	    ;; buffer buf-C is seen in live wind-C
	    (select-window wind-C)      ; must be displaying buf-C
	    (delete-other-windows)
	    (setq wind-C (selected-window))) ;FIXME: Why?
        (if three-way-comparison
	    (progn
	      ;; Buf-C was not set up yet as it wasn't visible,
	      ;; and use-same-frame = nil
              ;; Skip dedicated or iconified frames.
              ;; Unsplittable frames are taken care of later.
              (ediff-skip-unsuitable-frames 'ok-unsplittable)
	      (delete-other-windows)
	      (switch-to-buffer buf-C)
	      (setq wind-C (selected-window))
	      ))))

    (with-current-buffer control-buf
      (setq ediff-window-A wind-A
	    ediff-window-B wind-B
	    ediff-window-C wind-C)

      (setq frame-A (window-frame ediff-window-A)
	    designated-minibuffer-frame
	    (window-frame (minibuffer-window frame-A))))

    ;; It is unlikely that we'll implement a version of ediff-windows that
    ;; would compare 3 windows at once.  So, we don't use buffer C here.
    (if ediff-windows-job
	(progn
	  (set-window-start wind-A wind-A-start)
	  (set-window-start wind-B wind-B-start)))

    (ediff-setup-control-frame control-buf designated-minibuffer-frame)
    ))