123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- ;;; frame-fns.el --- Non-interactive frame and window functions.
- ;;
- ;; Filename: frame-fns.el
- ;; Description: Non-interactive frame and window functions.
- ;; Author: Drew Adams
- ;; Maintainer: Drew Adams
- ;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
- ;; Created: Tue Mar 5 16:15:50 1996
- ;; Version: 21.1
- ;; Last-Updated: Tue Jan 4 09:43:55 2011 (-0800)
- ;; By: dradams
- ;; Update #: 197
- ;; URL: http://www.emacswiki.org/cgi-bin/wiki/frame-fns.el
- ;; Keywords: internal, extensions, local, frames
- ;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
- ;;
- ;; Features that might be required by this library:
- ;;
- ;; `avoid'.
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; Commentary:
- ;;
- ;; Non-interactive frame and window functions.
- ;;
- ;; Main new functions defined here:
- ;;
- ;; `1-window-frames-on', `distance', `flash-ding',
- ;; `frame-geom-spec-cons', `frame-geom-value-cons',
- ;; `frame-geom-spec-numeric', `frame-geom-value-numeric',
- ;; `frames-on', `get-a-frame', `get-frame-name',
- ;; `multi-window-frames-on', `read-frame', `window-coords'.
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; Change log:
- ;;
- ;; 2011/01/04 dadams
- ;; Removed autoload cookies from non-interactive functions.
- ;; 2010/01/12 dadams
- ;; 1-window-frames-on, multi-window-frames-on:
- ;; save-excursion + set-buffer -> with-current-buffer.
- ;; 2008/04/05 dadams
- ;; get-a-frame: Define without using member-if.
- ;; 2005/10/31 dadams
- ;; read-frame: Swapped default and init values in call to completing-read.
- ;; 2004/11/26 dadams
- ;; Added frame-geom-spec-numeric and frame-geom-value-numeric.
- ;; 2004/03/19 dadams
- ;; read-frame: 1) if default is a frame, use its name,
- ;; 2) use frame-name-history, not minibuffer-history,
- ;; and use make-frame-names-alist, not frame-alist,
- ;; in completing-read
- ;; 1996/02/14 dadams
- ;; Added: window-coords, distance.
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; This program is free software; you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2, or (at your option)
- ;; any later version.
- ;; This program is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program; see the file COPYING. If not, write to
- ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- ;; Floor, Boston, MA 02110-1301, USA.
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; Code:
- (eval-when-compile (require 'cl)) ;; (plus, for Emacs 20: dolist, push
- ;; and, for Emacs <20: cadr, when, unless)
- (require 'avoid nil t) ;; mouse-avoidance-point-position
- ;;;;;;;;;;;;;;;;;;;;;;;
- (defun window-coords (&optional position)
- "Return window coordinates of buffer POSITION (default: point).
- If POSITION is nil, (point) is used."
- (unless (fboundp 'mouse-avoidance-point-position) (require 'avoid))
- (cdr (mouse-avoidance-point-position)))
- (defun distance (pt1 pt2)
- "Distance as the crow flies between PT1 and PT2.
- PT1 and PT2 are each a cons of the form (X . Y)."
- (let ((xdiff (abs (- (car pt1) (car pt2))))
- (ydiff (abs (- (cdr pt1) (cdr pt2)))))
- (sqrt (+ (* xdiff xdiff) (* ydiff ydiff)))))
- (defun frame-geom-value-numeric (type value &optional frame)
- "Return equivalent geometry value for FRAME in numeric terms.
- A geometry value equivalent to VALUE for FRAME is returned,
- where the value is numeric, not a consp.
- TYPE is the car of the original geometry spec (TYPE . VALUE).
- It is `top' or `left', depending on which edge VALUE is related to.
- VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
- If VALUE is a consp, then it is converted to a numeric value, perhaps
- relative to the opposite frame edge from that in the original spec.
- FRAME defaults to the selected frame.
- Examples (measures in pixels) -
- Assuming display height/width=1024, frame height/width=600:
- 300 inside display edge: 300 => 300
- (+ 300) => 300
- 300 inside opposite display edge: (- 300) => -300
- -300 => -300
- 300 beyond display edge
- (= 724 inside opposite display edge): (+ -300) => -724
- 300 beyond display edge
- (= 724 inside opposite display edge): (- -300) => 724
- In the last two examples, the returned value is relative to the
- opposite frame edge from the edge indicated in the input spec."
- (if (consp value)
- (if (natnump (cadr value))
- ;; e.g. (+ 300) or (- 300) => 300 or -300
- (funcall (car value) (cadr value))
- ;; e.g. (+ -300) or (- -300)
- (let ((oppval (- (if (eq 'left type)
- (x-display-pixel-width)
- (x-display-pixel-height))
- (cadr value)
- (if (eq 'left type)
- (frame-pixel-width frame)
- (frame-pixel-height frame)))))
- (if (eq '+ (car value))
- (- oppval) ; e.g. (+ -300) => -724
- oppval))) ; e.g. (- -300) => 724
- ;; e.g. 300 or -300
- value))
- (defun frame-geom-spec-numeric (spec &optional frame)
- "Return equivalent geometry specification for FRAME in numeric terms.
- A geometry specification equivalent to SPEC for FRAME is returned,
- where the value is numeric, not a consp.
- SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
- If VALUE is a consp, then it is converted to a numeric value, perhaps
- relative to the opposite frame edge from that in the original SPEC.
- FRAME defaults to the selected frame.
- Examples (measures in pixels) -
- Assuming display height=1024, frame height=600:
- top 300 below display top: (top . 300) => (top . 300)
- (top + 300) => (top . 300)
- bottom 300 above display bottom: (top - 300) => (top . -300)
- (top . -300) => (top . -300)
- top 300 above display top
- (= bottom 724 above display bottom): (top + -300) => (top . -724)
- bottom 300 below display bottom
- (= top 724 below display top): (top - -300) => (top . 724)
- In the last two examples, the returned value is relative to the
- opposite frame edge from the edge indicated in the input SPEC."
- (cons (car spec) (frame-geom-value-numeric (car spec) (cdr spec))))
- (defun frame-geom-value-cons (type value &optional frame)
- "Return equivalent geometry value for FRAME as a cons with car `+'.
- A geometry value equivalent to VALUE for FRAME is returned,
- where the value is a cons with car `+', not numeric.
- TYPE is the car of the original geometry spec (TYPE . VALUE).
- It is `top' or `left', depending on which edge VALUE is related to.
- VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
- If VALUE is a number, then it is converted to a cons value, perhaps
- relative to the opposite frame edge from that in the original spec.
- FRAME defaults to the selected frame.
- Examples (measures in pixels) -
- Assuming display height/width=1024, frame height/width=600:
- 300 inside display edge: 300 => (+ 300)
- (+ 300) => (+ 300)
- 300 inside opposite display edge: (- 300) => (+ 124)
- -300 => (+ 124)
- 300 beyond display edge
- (= 724 inside opposite display edge): (+ -300) => (+ -300)
- 300 beyond display edge
- (= 724 inside opposite display edge): (- -300) => (+ 724)
- In the 3rd, 4th, and 6th examples, the returned value is relative to
- the opposite frame edge from the edge indicated in the input spec."
- (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300)
- value)
- ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300)
- (t ; e.g. -300, (- 300), (- -300)
- (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724)
- (x-display-pixel-width)
- (x-display-pixel-height))
- (if (integerp value) (- value) (cadr value))
- (if (eq 'left type)
- (frame-pixel-width frame)
- (frame-pixel-height frame)))))))
- (defun frame-geom-spec-cons (spec &optional frame)
- "Return equivalent geometry spec for FRAME as a cons with car `+'.
- A geometry specification equivalent to SPEC for FRAME is returned,
- where the value is a cons with car `+', not numeric.
- SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
- If VALUE is a number, then it is converted to a cons value, perhaps
- relative to the opposite frame edge from that in the original spec.
- FRAME defaults to the selected frame.
- Examples (measures in pixels) -
- Assuming display height=1024, frame height=600:
- top 300 below display top: (top . 300) => (top + 300)
- (top + 300) => (top + 300)
- bottom 300 above display bottom: (top - 300) => (top + 124)
- (top . -300) => (top + 124)
- top 300 above display top
- (= bottom 724 above display bottom): (top + -300) => (top + -300)
- bottom 300 below display bottom
- (= top 724 below display top): (top - -300) => (top + 724)
- In the 3rd, 4th, and 6th examples, the returned value is relative to
- the opposite frame edge from the edge indicated in the input spec."
- (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec))))
- (defun get-frame-name (&optional frame)
- "Return the string that names FRAME (a frame). Default is selected frame."
- (unless frame (setq frame (selected-frame)))
- (if (framep frame)
- (cdr (assq 'name (frame-parameters frame)))
- (error "Function `get-frame-name': Argument not a frame: `%s'" frame)))
- (defun get-a-frame (frame)
- "Return a frame, if any, named FRAME (a frame or a string).
- If none, return nil.
- If FRAME is a frame, it is returned."
- (cond ((framep frame) frame)
- ((stringp frame)
- (catch 'get-a-frame-found
- (dolist (fr (frame-list))
- (when (string= frame (get-frame-name fr))
- (throw 'get-a-frame-found fr)))
- nil))
- (t
- (error
- "Function `get-frame-name': Arg neither a string nor a frame: `%s'"
- frame))))
- (defun read-frame (prompt &optional default existing)
- "Read the name of a frame, and return it as a string.
- Prompts with 1st arg, PROMPT (a string).
- The default frame is named by the optional 2nd arg, DEFAULT, if a
- string or a frame, or by the `selected-frame', if nil.
- Non-nil optional 3rd arg, EXISTING, means to allow only names of
- existing frames."
- (setq default (if (framep default) (get-frame-name default)
- (or default (get-frame-name))))
- (unless (stringp default)
- (error
- "Function `read-frame': DEFAULT arg is neither a frame nor a string"))
- (completing-read prompt (make-frame-names-alist)
- ;; To limit to live frames:
- ;; (function (lambda (fn+f)(frame-live-p (cdr fn+f))))
- ;; `frame-name-history' is defined in `frame.el'.
- nil existing nil '(frame-name-history . 2) default))
- (defun frames-on (buffer &optional frame)
- "List of all live frames showing BUFFER (a buffer or its name).
- The optional FRAME argument is as for function `get-buffer-window'."
- (filtered-frame-list (function (lambda (fr) (get-buffer-window buffer fr)))))
- (defun 1-window-frames-on (buffer)
- "List of all visible 1-window frames showing BUFFER."
- (setq buffer (get-buffer buffer))
- (when buffer ; Do nothing if BUFFER is not a buffer.
- (let ((frs nil))
- (with-current-buffer buffer
- (when (buffer-live-p buffer) ; Do nothing if dead buffer.
- (dolist (fr (frames-on buffer)) ; Is it better to search through
- (save-window-excursion ; frames-on or windows-on?
- (select-frame fr)
- (when (one-window-p t fr) (push fr frs))))))
- frs)))
- (defun multi-window-frames-on (buffer)
- "List of all visible multi-window frames showing BUFFER."
- (setq buffer (get-buffer buffer))
- (when buffer ; Do nothing if BUFFER is not a buffer.
- (let ((frs nil))
- (with-current-buffer buffer
- (when (buffer-live-p buffer) ; Do nothing if dead buffer.
- (dolist (fr (frames-on buffer)) ; Is it better to search through
- (save-window-excursion ; frames-on or windows-on?
- (select-frame fr)
- (when (not (one-window-p t fr)) (push fr frs))))))
- frs)))
- (defun flash-ding (&optional do-not-terminate frame)
- "Ring bell (`ding'), after flashing FRAME (default: current), if relevant.
- Terminates any keyboard macro executing, unless arg DO-NOT-TERMINATE non-nil."
- (save-window-excursion
- (when frame (select-frame frame))
- (let ((visible-bell t)) ; Flash.
- (ding do-not-terminate)))
- (let ((visible-bell nil))
- (ding do-not-terminate))) ; Bell.
- ;;;;;;;;;;;;;;;;;;;;;;;
- (provide 'frame-fns)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; frame-fns.el ends here
|