Checked anti.texi, errors.texi, and maps.texi.
[bpt/emacs.git] / lisp / frame.el
... / ...
CommitLineData
1;;; frame.el --- multi-frame management independent of window systems
2
3;; Copyright (C) 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2003,
4;; 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
6;; Maintainer: FSF
7;; Keywords: internal
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software: you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23
24;;; Commentary:
25
26;;; Code:
27
28(defvar frame-creation-function-alist
29 (list (cons nil
30 (if (fboundp 'tty-create-frame-with-faces)
31 'tty-create-frame-with-faces
32 (lambda (parameters)
33 (error "Can't create multiple frames without a window system")))))
34 "Alist of window-system dependent functions to call to create a new frame.
35The window system startup file should add its frame creation
36function to this list, which should take an alist of parameters
37as its argument.")
38
39(defvar window-system-default-frame-alist nil
40 "Alist of window-system dependent default frame parameters.
41You can set this in your init file; for example,
42
43 ;; Disable menubar and toolbar on the console, but enable them under X.
44 (setq window-system-default-frame-alist
45 '((x (menu-bar-lines . 1) (tool-bar-lines . 1))
46 (nil (menu-bar-lines . 0) (tool-bar-lines . 0))))
47
48Parameters specified here supersede the values given in
49`default-frame-alist'.")
50
51;; The initial value given here used to ask for a minibuffer.
52;; But that's not necessary, because the default is to have one.
53;; By not specifying it here, we let an X resource specify it.
54(defcustom initial-frame-alist nil
55 "Alist of parameters for the initial X window frame.
56You can set this in your init file; for example,
57
58 (setq initial-frame-alist
59 '((top . 1) (left . 1) (width . 80) (height . 55)))
60
61Parameters specified here supersede the values given in
62`default-frame-alist'.
63
64If the value calls for a frame without a minibuffer, and you have
65not created a minibuffer frame on your own, a minibuffer frame is
66created according to `minibuffer-frame-alist'.
67
68You can specify geometry-related options for just the initial
69frame by setting this variable in your init file; however, they
70won't take effect until Emacs reads your init file, which happens
71after creating the initial frame. If you want the initial frame
72to have the proper geometry as soon as it appears, you need to
73use this three-step process:
74* Specify X resources to give the geometry you want.
75* Set `default-frame-alist' to override these options so that they
76 don't affect subsequent frames.
77* Set `initial-frame-alist' in a way that matches the X resources,
78 to override what you put in `default-frame-alist'."
79 :type '(repeat (cons :format "%v"
80 (symbol :tag "Parameter")
81 (sexp :tag "Value")))
82 :group 'frames)
83
84(defcustom minibuffer-frame-alist '((width . 80) (height . 2))
85 "Alist of parameters for initial minibuffer frame.
86You can set this in your init file; for example,
87
88 (setq minibuffer-frame-alist
89 '((top . 1) (left . 1) (width . 80) (height . 2)))
90
91Parameters specified here supersede the values given in
92`default-frame-alist', for a minibuffer frame."
93 :type '(repeat (cons :format "%v"
94 (symbol :tag "Parameter")
95 (sexp :tag "Value")))
96 :group 'frames)
97
98(defcustom pop-up-frame-alist nil
99 "Alist of parameters for automatically generated new frames.
100You can set this in your init file; for example,
101
102 (setq pop-up-frame-alist '((width . 80) (height . 20)))
103
104If non-nil, the value you specify here is used by the default
105`pop-up-frame-function' for the creation of new frames.
106
107Since `pop-up-frame-function' is used by `display-buffer' for
108making new frames, any value specified here by default affects
109the automatic generation of new frames via `display-buffer' and
110all functions based on it. The behavior of `make-frame' is not
111affected by this variable."
112 :type '(repeat (cons :format "%v"
113 (symbol :tag "Parameter")
114 (sexp :tag "Value")))
115 :group 'frames)
116
117(defcustom pop-up-frame-function
118 (lambda () (make-frame pop-up-frame-alist))
119 "Function used by `display-buffer' for creating a new frame.
120This function is called with no arguments and should return a new
121frame. The default value calls `make-frame' with the argument
122`pop-up-frame-alist'."
123 :type 'function
124 :group 'frames)
125
126(defcustom special-display-frame-alist
127 '((height . 14) (width . 80) (unsplittable . t))
128 "Alist of parameters for special frames.
129Special frames are used for buffers whose names are listed in
130`special-display-buffer-names' and for buffers whose names match
131one of the regular expressions in `special-display-regexps'.
132
133This variable can be set in your init file, like this:
134
135 (setq special-display-frame-alist '((width . 80) (height . 20)))
136
137These supersede the values given in `default-frame-alist'."
138 :type '(repeat (cons :format "%v"
139 (symbol :tag "Parameter")
140 (sexp :tag "Value")))
141 :group 'frames)
142
143(defun special-display-popup-frame (buffer &optional args)
144 "Display BUFFER and return the window chosen.
145If BUFFER is already displayed in a visible or iconified frame,
146raise that frame. Otherwise, display BUFFER in a new frame.
147
148Optional argument ARGS is a list specifying additional
149information.
150
151If ARGS is an alist, use it as a list of frame parameters. If
152these parameters contain \(same-window . t), display BUFFER in
153the selected window. If they contain \(same-frame . t), display
154BUFFER in a window of the selected frame.
155
156If ARGS is a list whose car is a symbol, use (car ARGS) as a
157function to do the work. Pass it BUFFER as first argument,
158and (cdr ARGS) as second."
159 (if (and args (symbolp (car args)))
160 (apply (car args) buffer (cdr args))
161 (let ((window (get-buffer-window buffer 0)))
162 (or
163 ;; If we have a window already, make it visible.
164 (when window
165 (let ((frame (window-frame window)))
166 (make-frame-visible frame)
167 (raise-frame frame)
168 window))
169 ;; Reuse the current window if the user requested it.
170 (when (cdr (assq 'same-window args))
171 (condition-case nil
172 (progn (switch-to-buffer buffer) (selected-window))
173 (error nil)))
174 ;; Stay on the same frame if requested.
175 (when (or (cdr (assq 'same-frame args)) (cdr (assq 'same-window args)))
176 (let* ((pop-up-windows t)
177 pop-up-frames
178 special-display-buffer-names special-display-regexps)
179 (display-buffer buffer)))
180 ;; If no window yet, make one in a new frame.
181 (let ((frame
182 (with-current-buffer buffer
183 (make-frame (append args special-display-frame-alist)))))
184 (set-window-buffer (frame-selected-window frame) buffer)
185 (set-window-dedicated-p (frame-selected-window frame) t)
186 (frame-selected-window frame))))))
187
188(defun handle-delete-frame (event)
189 "Handle delete-frame events from the X server."
190 (interactive "e")
191 (let ((frame (posn-window (event-start event)))
192 (i 0)
193 (tail (frame-list)))
194 (while tail
195 (and (frame-visible-p (car tail))
196 (not (eq (car tail) frame))
197 (setq i (1+ i)))
198 (setq tail (cdr tail)))
199 (if (> i 0)
200 (delete-frame frame t)
201 ;; Gildea@x.org says it is ok to ask questions before terminating.
202 (save-buffers-kill-emacs))))
203\f
204;;;; Arrangement of frames at startup
205
206;; 1) Load the window system startup file from the lisp library and read the
207;; high-priority arguments (-q and the like). The window system startup
208;; file should create any frames specified in the window system defaults.
209;;
210;; 2) If no frames have been opened, we open an initial text frame.
211;;
212;; 3) Once the init file is done, we apply any newly set parameters
213;; in initial-frame-alist to the frame.
214
215;; These are now called explicitly at the proper times,
216;; since that is easier to understand.
217;; Actually using hooks within Emacs is bad for future maintenance. --rms.
218;; (add-hook 'before-init-hook 'frame-initialize)
219;; (add-hook 'window-setup-hook 'frame-notice-user-settings)
220
221;; If we create the initial frame, this is it.
222(defvar frame-initial-frame nil)
223
224;; Record the parameters used in frame-initialize to make the initial frame.
225(defvar frame-initial-frame-alist)
226
227(defvar frame-initial-geometry-arguments nil)
228
229;; startup.el calls this function before loading the user's init
230;; file - if there is no frame with a minibuffer open now, create
231;; one to display messages while loading the init file.
232(defun frame-initialize ()
233 "Create an initial frame if necessary."
234 ;; Are we actually running under a window system at all?
235 (if (and initial-window-system
236 (not noninteractive)
237 (not (eq initial-window-system 'pc)))
238 (progn
239 ;; If there is no frame with a minibuffer besides the terminal
240 ;; frame, then we need to create the opening frame. Make sure
241 ;; it has a minibuffer, but let initial-frame-alist omit the
242 ;; minibuffer spec.
243 (or (delq terminal-frame (minibuffer-frame-list))
244 (progn
245 (setq frame-initial-frame-alist
246 (append initial-frame-alist default-frame-alist nil))
247 (or (assq 'horizontal-scroll-bars frame-initial-frame-alist)
248 (setq frame-initial-frame-alist
249 (cons '(horizontal-scroll-bars . t)
250 frame-initial-frame-alist)))
251 (setq frame-initial-frame-alist
252 (cons (cons 'window-system initial-window-system)
253 frame-initial-frame-alist))
254 (setq default-minibuffer-frame
255 (setq frame-initial-frame
256 (make-frame frame-initial-frame-alist)))
257 ;; Delete any specifications for window geometry parameters
258 ;; so that we won't reapply them in frame-notice-user-settings.
259 ;; It would be wrong to reapply them then,
260 ;; because that would override explicit user resizing.
261 (setq initial-frame-alist
262 (frame-remove-geometry-params initial-frame-alist))))
263 ;; Copy the environment of the Emacs process into the new frame.
264 (set-frame-parameter frame-initial-frame 'environment
265 (frame-parameter terminal-frame 'environment))
266 ;; At this point, we know that we have a frame open, so we
267 ;; can delete the terminal frame.
268 (delete-frame terminal-frame)
269 (setq terminal-frame nil))))
270
271(defvar frame-notice-user-settings t
272 "Non-nil means function `frame-notice-user-settings' wasn't run yet.")
273
274(declare-function tool-bar-mode "tool-bar" (&optional arg))
275
276;; startup.el calls this function after loading the user's init
277;; file. Now default-frame-alist and initial-frame-alist contain
278;; information to which we must react; do what needs to be done.
279(defun frame-notice-user-settings ()
280 "Act on user's init file settings of frame parameters.
281React to settings of `initial-frame-alist',
282`window-system-default-frame-alist' and `default-frame-alist'
283there (in decreasing order of priority)."
284 ;; Make menu-bar-mode and default-frame-alist consistent.
285 (when (boundp 'menu-bar-mode)
286 (let ((default (assq 'menu-bar-lines default-frame-alist)))
287 (if default
288 (setq menu-bar-mode (not (eq (cdr default) 0)))
289 (setq default-frame-alist
290 (cons (cons 'menu-bar-lines (if menu-bar-mode 1 0))
291 default-frame-alist)))))
292
293 ;; Make tool-bar-mode and default-frame-alist consistent. Don't do
294 ;; it in batch mode since that would leave a tool-bar-lines
295 ;; parameter in default-frame-alist in a dumped Emacs, which is not
296 ;; what we want.
297 (when (and (boundp 'tool-bar-mode)
298 (not noninteractive))
299 (let ((default (assq 'tool-bar-lines default-frame-alist)))
300 (if default
301 (setq tool-bar-mode (not (eq (cdr default) 0)))
302 ;; If Emacs was started on a tty, changing default-frame-alist
303 ;; would disable the toolbar on X frames created later. We
304 ;; want to keep the default of showing a toolbar under X even
305 ;; in this case.
306 ;;
307 ;; If the user explicitly called `tool-bar-mode' in .emacs,
308 ;; then default-frame-alist is already changed anyway.
309 (when initial-window-system
310 (setq default-frame-alist
311 (cons (cons 'tool-bar-lines (if tool-bar-mode 1 0))
312 default-frame-alist))))))
313
314 ;; Creating and deleting frames may shift the selected frame around,
315 ;; and thus the current buffer. Protect against that. We don't
316 ;; want to use save-excursion here, because that may also try to set
317 ;; the buffer of the selected window, which fails when the selected
318 ;; window is the minibuffer.
319 (let ((old-buffer (current-buffer))
320 (window-system-frame-alist
321 (cdr (assq initial-window-system
322 window-system-default-frame-alist))))
323
324 (when (and frame-notice-user-settings
325 (null frame-initial-frame))
326 ;; This case happens when we don't have a window system, and
327 ;; also for MS-DOS frames.
328 (let ((parms (frame-parameters frame-initial-frame)))
329 ;; Don't change the frame names.
330 (setq parms (delq (assq 'name parms) parms))
331 ;; Can't modify the minibuffer parameter, so don't try.
332 (setq parms (delq (assq 'minibuffer parms) parms))
333 (modify-frame-parameters nil
334 (if (null initial-window-system)
335 (append initial-frame-alist
336 window-system-frame-alist
337 default-frame-alist
338 parms
339 nil)
340 ;; initial-frame-alist and
341 ;; default-frame-alist were already
342 ;; applied in pc-win.el.
343 parms))
344 (if (null initial-window-system) ;; MS-DOS does this differently in pc-win.el
345 (let ((newparms (frame-parameters))
346 (frame (selected-frame)))
347 (tty-handle-reverse-video frame newparms)
348 ;; If we changed the background color, we need to update
349 ;; the background-mode parameter, and maybe some faces,
350 ;; too.
351 (when (assq 'background-color newparms)
352 (unless (or (assq 'background-mode initial-frame-alist)
353 (assq 'background-mode default-frame-alist))
354 (frame-set-background-mode frame))
355 (face-set-after-frame-default frame))))))
356
357 ;; If the initial frame is still around, apply initial-frame-alist
358 ;; and default-frame-alist to it.
359 (when (frame-live-p frame-initial-frame)
360
361 ;; When tool-bar has been switched off, correct the frame size
362 ;; by the lines added in x-create-frame for the tool-bar and
363 ;; switch `tool-bar-mode' off.
364 (when (display-graphic-p)
365 (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
366 (assq 'tool-bar-lines window-system-frame-alist)
367 (assq 'tool-bar-lines default-frame-alist))))
368 (when (and tool-bar-originally-present
369 (or (null tool-bar-lines)
370 (null (cdr tool-bar-lines))
371 (eq 0 (cdr tool-bar-lines))))
372 (let* ((char-height (frame-char-height frame-initial-frame))
373 (image-height tool-bar-images-pixel-height)
374 (margin (cond ((and (consp tool-bar-button-margin)
375 (integerp (cdr tool-bar-button-margin))
376 (> tool-bar-button-margin 0))
377 (cdr tool-bar-button-margin))
378 ((and (integerp tool-bar-button-margin)
379 (> tool-bar-button-margin 0))
380 tool-bar-button-margin)
381 (t 0)))
382 (relief (if (and (integerp tool-bar-button-relief)
383 (> tool-bar-button-relief 0))
384 tool-bar-button-relief 3))
385 (lines (/ (+ image-height
386 (* 2 margin)
387 (* 2 relief)
388 (1- char-height))
389 char-height))
390 (height (frame-parameter frame-initial-frame 'height))
391 (newparms (list (cons 'height (- height lines))))
392 (initial-top (cdr (assq 'top
393 frame-initial-geometry-arguments)))
394 (top (frame-parameter frame-initial-frame 'top)))
395 (when (and (consp initial-top) (eq '- (car initial-top)))
396 (let ((adjusted-top
397 (cond ((and (consp top)
398 (eq '+ (car top)))
399 (list '+
400 (+ (cadr top)
401 (* lines char-height))))
402 ((and (consp top)
403 (eq '- (car top)))
404 (list '-
405 (- (cadr top)
406 (* lines char-height))))
407 (t (+ top (* lines char-height))))))
408 (setq newparms
409 (append newparms
410 `((top . ,adjusted-top))
411 nil))))
412 (modify-frame-parameters frame-initial-frame newparms)
413 (tool-bar-mode -1)))))
414
415 ;; The initial frame we create above always has a minibuffer.
416 ;; If the user wants to remove it, or make it a minibuffer-only
417 ;; frame, then we'll have to delete the current frame and make a
418 ;; new one; you can't remove or add a root window to/from an
419 ;; existing frame.
420 ;;
421 ;; NOTE: default-frame-alist was nil when we created the
422 ;; existing frame. We need to explicitly include
423 ;; default-frame-alist in the parameters of the screen we
424 ;; create here, so that its new value, gleaned from the user's
425 ;; .emacs file, will be applied to the existing screen.
426 (if (not (eq (cdr (or (assq 'minibuffer initial-frame-alist)
427 (assq 'minibuffer window-system-frame-alist)
428 (assq 'minibuffer default-frame-alist)
429 '(minibuffer . t)))
430 t))
431 ;; Create the new frame.
432 (let (parms new)
433 ;; If the frame isn't visible yet, wait till it is.
434 ;; If the user has to position the window,
435 ;; Emacs doesn't know its real position until
436 ;; the frame is seen to be visible.
437 (while (not (cdr (assq 'visibility
438 (frame-parameters frame-initial-frame))))
439 (sleep-for 1))
440 (setq parms (frame-parameters frame-initial-frame))
441
442 ;; Get rid of `name' unless it was specified explicitly before.
443 (or (assq 'name frame-initial-frame-alist)
444 (setq parms (delq (assq 'name parms) parms)))
445 ;; An explicit parent-id is a request to XEmbed the frame.
446 (or (assq 'parent-id frame-initial-frame-alist)
447 (setq parms (delq (assq 'parent-id parms) parms)))
448
449 (setq parms (append initial-frame-alist
450 window-system-frame-alist
451 default-frame-alist
452 parms
453 nil))
454
455 ;; Get rid of `reverse', because that was handled
456 ;; when we first made the frame.
457 (setq parms (cons '(reverse) (delq (assq 'reverse parms) parms)))
458
459 (if (assq 'height frame-initial-geometry-arguments)
460 (setq parms (assq-delete-all 'height parms)))
461 (if (assq 'width frame-initial-geometry-arguments)
462 (setq parms (assq-delete-all 'width parms)))
463 (if (assq 'left frame-initial-geometry-arguments)
464 (setq parms (assq-delete-all 'left parms)))
465 (if (assq 'top frame-initial-geometry-arguments)
466 (setq parms (assq-delete-all 'top parms)))
467 (setq new
468 (make-frame
469 ;; Use the geometry args that created the existing
470 ;; frame, rather than the parms we get for it.
471 (append frame-initial-geometry-arguments
472 '((user-size . t) (user-position . t))
473 parms)))
474 ;; The initial frame, which we are about to delete, may be
475 ;; the only frame with a minibuffer. If it is, create a
476 ;; new one.
477 (or (delq frame-initial-frame (minibuffer-frame-list))
478 (make-initial-minibuffer-frame nil))
479
480 ;; If the initial frame is serving as a surrogate
481 ;; minibuffer frame for any frames, we need to wean them
482 ;; onto a new frame. The default-minibuffer-frame
483 ;; variable must be handled similarly.
484 (let ((users-of-initial
485 (filtered-frame-list
486 (lambda (frame)
487 (and (not (eq frame frame-initial-frame))
488 (eq (window-frame
489 (minibuffer-window frame))
490 frame-initial-frame))))))
491 (if (or users-of-initial
492 (eq default-minibuffer-frame frame-initial-frame))
493
494 ;; Choose an appropriate frame. Prefer frames which
495 ;; are only minibuffers.
496 (let* ((new-surrogate
497 (car
498 (or (filtered-frame-list
499 (lambda (frame)
500 (eq (cdr (assq 'minibuffer
501 (frame-parameters frame)))
502 'only)))
503 (minibuffer-frame-list))))
504 (new-minibuffer (minibuffer-window new-surrogate)))
505
506 (if (eq default-minibuffer-frame frame-initial-frame)
507 (setq default-minibuffer-frame new-surrogate))
508
509 ;; Wean the frames using frame-initial-frame as
510 ;; their minibuffer frame.
511 (dolist (frame users-of-initial)
512 (modify-frame-parameters
513 frame (list (cons 'minibuffer new-minibuffer)))))))
514
515 ;; Redirect events enqueued at this frame to the new frame.
516 ;; Is this a good idea?
517 (redirect-frame-focus frame-initial-frame new)
518
519 ;; Finally, get rid of the old frame.
520 (delete-frame frame-initial-frame t))
521
522 ;; Otherwise, we don't need all that rigamarole; just apply
523 ;; the new parameters.
524 (let (newparms allparms tail)
525 (setq allparms (append initial-frame-alist
526 window-system-frame-alist
527 default-frame-alist nil))
528 (if (assq 'height frame-initial-geometry-arguments)
529 (setq allparms (assq-delete-all 'height allparms)))
530 (if (assq 'width frame-initial-geometry-arguments)
531 (setq allparms (assq-delete-all 'width allparms)))
532 (if (assq 'left frame-initial-geometry-arguments)
533 (setq allparms (assq-delete-all 'left allparms)))
534 (if (assq 'top frame-initial-geometry-arguments)
535 (setq allparms (assq-delete-all 'top allparms)))
536 (setq tail allparms)
537 ;; Find just the parms that have changed since we first
538 ;; made this frame. Those are the ones actually set by
539 ;; the init file. For those parms whose values we already knew
540 ;; (such as those spec'd by command line options)
541 ;; it is undesirable to specify the parm again
542 ;; once the user has seen the frame and been able to alter it
543 ;; manually.
544 (while tail
545 (let (newval oldval)
546 (setq oldval (assq (car (car tail))
547 frame-initial-frame-alist))
548 (setq newval (cdr (assq (car (car tail)) allparms)))
549 (or (and oldval (eq (cdr oldval) newval))
550 (setq newparms
551 (cons (cons (car (car tail)) newval) newparms))))
552 (setq tail (cdr tail)))
553 (setq newparms (nreverse newparms))
554 (modify-frame-parameters frame-initial-frame
555 newparms)
556 ;; If we changed the background color,
557 ;; we need to update the background-mode parameter
558 ;; and maybe some faces too.
559 (when (assq 'background-color newparms)
560 (unless (assq 'background-mode newparms)
561 (frame-set-background-mode frame-initial-frame))
562 (face-set-after-frame-default frame-initial-frame)))))
563
564 ;; Restore the original buffer.
565 (set-buffer old-buffer)
566
567 ;; Make sure the initial frame can be GC'd if it is ever deleted.
568 ;; Make sure frame-notice-user-settings does nothing if called twice.
569 (setq frame-notice-user-settings nil)
570 (setq frame-initial-frame nil)))
571
572(defun make-initial-minibuffer-frame (display)
573 (let ((parms (append minibuffer-frame-alist '((minibuffer . only)))))
574 (if display
575 (make-frame-on-display display parms)
576 (make-frame parms))))
577
578;;;; Creation of additional frames, and other frame miscellanea
579
580(defun modify-all-frames-parameters (alist)
581 "Modify all current and future frames' parameters according to ALIST.
582This changes `default-frame-alist' and possibly `initial-frame-alist'.
583Furthermore, this function removes all parameters in ALIST from
584`window-system-default-frame-alist'.
585See help of `modify-frame-parameters' for more information."
586 (dolist (frame (frame-list))
587 (modify-frame-parameters frame alist))
588
589 (dolist (pair alist) ;; conses to add/replace
590 ;; initial-frame-alist needs setting only when
591 ;; frame-notice-user-settings is true.
592 (and frame-notice-user-settings
593 (setq initial-frame-alist
594 (assq-delete-all (car pair) initial-frame-alist)))
595 (setq default-frame-alist
596 (assq-delete-all (car pair) default-frame-alist))
597 ;; Remove any similar settings from the window-system specific
598 ;; parameters---they would override default-frame-alist.
599 (dolist (w window-system-default-frame-alist)
600 (setcdr w (assq-delete-all (car pair) (cdr w)))))
601
602 (and frame-notice-user-settings
603 (setq initial-frame-alist (append initial-frame-alist alist)))
604 (setq default-frame-alist (append default-frame-alist alist)))
605
606(defun get-other-frame ()
607 "Return some frame other than the current frame.
608Create one if necessary. Note that the minibuffer frame, if separate,
609is not considered (see `next-frame')."
610 (let ((s (if (equal (next-frame (selected-frame)) (selected-frame))
611 (make-frame)
612 (next-frame (selected-frame)))))
613 s))
614
615(defun next-multiframe-window ()
616 "Select the next window, regardless of which frame it is on."
617 (interactive)
618 (select-window (next-window (selected-window)
619 (> (minibuffer-depth) 0)
620 0))
621 (select-frame-set-input-focus (selected-frame)))
622
623(defun previous-multiframe-window ()
624 "Select the previous window, regardless of which frame it is on."
625 (interactive)
626 (select-window (previous-window (selected-window)
627 (> (minibuffer-depth) 0)
628 0))
629 (select-frame-set-input-focus (selected-frame)))
630
631(declare-function x-initialize-window-system "term/x-win" ())
632(declare-function ns-initialize-window-system "term/ns-win" ())
633(defvar x-display-name) ; term/x-win
634
635(defun make-frame-on-display (display &optional parameters)
636 "Make a frame on display DISPLAY.
637The optional argument PARAMETERS specifies additional frame parameters."
638 (interactive "sMake frame on display: ")
639 (cond ((featurep 'ns)
640 (when (and (boundp 'ns-initialized) (not ns-initialized))
641 (setq x-display-name display)
642 (ns-initialize-window-system))
643 (make-frame `((window-system . ns)
644 (display . ,display) . ,parameters)))
645 ((eq system-type 'windows-nt)
646 ;; On Windows, ignore DISPLAY.
647 (make-frame parameters))
648 (t
649 (unless (string-match-p "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
650 (error "Invalid display, not HOST:SERVER or HOST:SERVER.SCREEN"))
651 (when (and (boundp 'x-initialized) (not x-initialized))
652 (setq x-display-name display)
653 (x-initialize-window-system))
654 (make-frame `((window-system . x)
655 (display . ,display) . ,parameters)))))
656
657(declare-function x-close-connection "xfns.c" (terminal))
658
659(defun close-display-connection (display)
660 "Close the connection to a display, deleting all its associated frames.
661For DISPLAY, specify either a frame or a display name (a string).
662If DISPLAY is nil, that stands for the selected frame's display."
663 (interactive
664 (list
665 (let* ((default (frame-parameter nil 'display))
666 (display (completing-read
667 (format "Close display (default %s): " default)
668 (delete-dups
669 (mapcar (lambda (frame)
670 (frame-parameter frame 'display))
671 (frame-list)))
672 nil t nil nil
673 default)))
674 (if (zerop (length display)) default display))))
675 (let ((frames (delq nil
676 (mapcar (lambda (frame)
677 (if (equal display
678 (frame-parameter frame 'display))
679 frame))
680 (frame-list)))))
681 (if (and (consp frames)
682 (not (y-or-n-p (if (cdr frames)
683 (format "Delete %s frames? " (length frames))
684 (format "Delete %s ? " (car frames))))))
685 (error "Abort!")
686 (mapc 'delete-frame frames)
687 (x-close-connection display))))
688
689(defun make-frame-command ()
690 "Make a new frame, on the same terminal as the selected frame.
691If the terminal is a text-only terminal, this also selects the
692new frame."
693 (interactive)
694 (if (display-graphic-p)
695 (make-frame)
696 (select-frame (make-frame))))
697
698(defvar before-make-frame-hook nil
699 "Functions to run before a frame is created.")
700
701(defvar after-make-frame-functions nil
702 "Functions to run after a frame is created.
703The functions are run with one arg, the newly created frame.")
704
705(defvar after-setting-font-hook nil
706 "Functions to run after a frame's font has been changed.")
707
708;; Alias, kept temporarily.
709(define-obsolete-function-alias 'new-frame 'make-frame "22.1")
710
711(defvar frame-inherited-parameters '()
712 ;; FIXME: Shouldn't we add `font' here as well?
713 "Parameters `make-frame' copies from the `selected-frame' to the new frame.")
714
715(defun make-frame (&optional parameters)
716 "Return a newly created frame displaying the current buffer.
717Optional argument PARAMETERS is an alist of parameters for the new frame.
718Each element of PARAMETERS should have the form (NAME . VALUE), for example:
719
720 (name . STRING) The frame should be named STRING.
721
722 (width . NUMBER) The frame should be NUMBER characters in width.
723 (height . NUMBER) The frame should be NUMBER text lines high.
724
725You cannot specify either `width' or `height', you must use neither or both.
726
727 (minibuffer . t) The frame should have a minibuffer.
728 (minibuffer . nil) The frame should have no minibuffer.
729 (minibuffer . only) The frame should contain only a minibuffer.
730 (minibuffer . WINDOW) The frame should use WINDOW as its minibuffer window.
731
732 (window-system . nil) The frame should be displayed on a terminal device.
733 (window-system . x) The frame should be displayed in an X window.
734
735 (terminal . TERMINAL) The frame should use the terminal object TERMINAL.
736
737Before the frame is created (via `frame-creation-function-alist'), functions on the
738hook `before-make-frame-hook' are run. After the frame is created, functions
739on `after-make-frame-functions' are run with one arg, the newly created frame.
740
741This function itself does not make the new frame the selected frame.
742The previously selected frame remains selected. However, the
743window system may select the new frame for its own reasons, for
744instance if the frame appears under the mouse pointer and your
745setup is for focus to follow the pointer."
746 (interactive)
747 (let* ((w (cond
748 ((assq 'terminal parameters)
749 (let ((type (terminal-live-p (cdr (assq 'terminal parameters)))))
750 (cond
751 ((eq type t) nil)
752 ((eq type nil) (error "Terminal %s does not exist"
753 (cdr (assq 'terminal parameters))))
754 (t type))))
755 ((assq 'window-system parameters)
756 (cdr (assq 'window-system parameters)))
757 (t window-system)))
758 (frame-creation-function (cdr (assq w frame-creation-function-alist)))
759 (oldframe (selected-frame))
760 frame)
761 (unless frame-creation-function
762 (error "Don't know how to create a frame on window system %s" w))
763 (run-hooks 'before-make-frame-hook)
764 (setq frame
765 (funcall frame-creation-function
766 (append parameters
767 (cdr (assq w window-system-default-frame-alist)))))
768 (normal-erase-is-backspace-setup-frame frame)
769 ;; Inherit the original frame's parameters.
770 (dolist (param frame-inherited-parameters)
771 (unless (assq param parameters) ;Overridden by explicit parameters.
772 (let ((val (frame-parameter oldframe param)))
773 (when val (set-frame-parameter frame param val)))))
774 (run-hook-with-args 'after-make-frame-functions frame)
775 frame))
776
777(defun filtered-frame-list (predicate)
778 "Return a list of all live frames which satisfy PREDICATE."
779 (let* ((frames (frame-list))
780 (list frames))
781 (while (consp frames)
782 (unless (funcall predicate (car frames))
783 (setcar frames nil))
784 (setq frames (cdr frames)))
785 (delq nil list)))
786
787(defun minibuffer-frame-list ()
788 "Return a list of all frames with their own minibuffers."
789 (filtered-frame-list
790 (lambda (frame)
791 (eq frame (window-frame (minibuffer-window frame))))))
792
793;; Used to be called `terminal-id' in termdev.el.
794(defun get-device-terminal (device)
795 "Return the terminal corresponding to DEVICE.
796DEVICE can be a terminal, a frame, nil (meaning the selected frame's terminal),
797the name of an X display device (HOST.SERVER.SCREEN) or a tty device file."
798 (cond
799 ((or (null device) (framep device))
800 (frame-terminal device))
801 ((stringp device)
802 (let ((f (car (filtered-frame-list
803 (lambda (frame)
804 (or (equal (frame-parameter frame 'display) device)
805 (equal (frame-parameter frame 'tty) device)))))))
806 (or f (error "Display %s does not exist" device))
807 (frame-terminal f)))
808 ((terminal-live-p device) device)
809 (t
810 (error "Invalid argument %s in `get-device-terminal'" device))))
811
812(defun frames-on-display-list (&optional device)
813 "Return a list of all frames on DEVICE.
814
815DEVICE should be a terminal, a frame,
816or a name of an X display or tty (a string of the form
817HOST:SERVER.SCREEN).
818
819If DEVICE is omitted or nil, it defaults to the selected
820frame's terminal device."
821 (let* ((terminal (get-device-terminal device))
822 (func #'(lambda (frame)
823 (eq (frame-terminal frame) terminal))))
824 (filtered-frame-list func)))
825
826(defun framep-on-display (&optional terminal)
827 "Return the type of frames on TERMINAL.
828TERMINAL may be a terminal id, a display name or a frame. If it
829is a frame, its type is returned. If TERMINAL is omitted or nil,
830it defaults to the selected frame's terminal device. All frames
831on a given display are of the same type."
832 (or (terminal-live-p terminal)
833 (framep terminal)
834 (framep (car (frames-on-display-list terminal)))))
835
836(defun frame-remove-geometry-params (param-list)
837 "Return the parameter list PARAM-LIST, but with geometry specs removed.
838This deletes all bindings in PARAM-LIST for `top', `left', `width',
839`height', `user-size' and `user-position' parameters.
840Emacs uses this to avoid overriding explicit moves and resizings from
841the user during startup."
842 (setq param-list (cons nil param-list))
843 (let ((tail param-list))
844 (while (consp (cdr tail))
845 (if (and (consp (car (cdr tail)))
846 (memq (car (car (cdr tail)))
847 '(height width top left user-position user-size)))
848 (progn
849 (setq frame-initial-geometry-arguments
850 (cons (car (cdr tail)) frame-initial-geometry-arguments))
851 (setcdr tail (cdr (cdr tail))))
852 (setq tail (cdr tail)))))
853 (setq frame-initial-geometry-arguments
854 (nreverse frame-initial-geometry-arguments))
855 (cdr param-list))
856
857(declare-function x-focus-frame "xfns.c" (frame))
858
859(defun select-frame-set-input-focus (frame)
860 "Select FRAME, raise it, and set input focus, if possible.
861If `mouse-autoselect-window' is non-nil, also move mouse cursor
862to FRAME's selected window. Otherwise, if `focus-follows-mouse'
863is non-nil, move mouse cursor to FRAME."
864 (select-frame frame)
865 (raise-frame frame)
866 ;; Ensure, if possible, that FRAME gets input focus.
867 (when (memq (window-system frame) '(x w32 ns))
868 (x-focus-frame frame))
869 ;; Move mouse cursor if necessary.
870 (cond
871 (mouse-autoselect-window
872 (let ((edges (window-inside-edges (frame-selected-window frame))))
873 ;; Move mouse cursor into FRAME's selected window to avoid that
874 ;; Emacs mouse-autoselects another window.
875 (set-mouse-position frame (nth 2 edges) (nth 1 edges))))
876 (focus-follows-mouse
877 ;; Move mouse cursor into FRAME to avoid that another frame gets
878 ;; selected by the window manager.
879 (set-mouse-position frame (1- (frame-width frame)) 0))))
880
881(defun other-frame (arg)
882 "Select the ARGth different visible frame on current display, and raise it.
883All frames are arranged in a cyclic order.
884This command selects the frame ARG steps away in that order.
885A negative ARG moves in the opposite order.
886
887To make this command work properly, you must tell Emacs
888how the system (or the window manager) generally handles
889focus-switching between windows. If moving the mouse onto a window
890selects it (gives it focus), set `focus-follows-mouse' to t.
891Otherwise, that variable should be nil."
892 (interactive "p")
893 (let ((frame (selected-frame)))
894 (while (> arg 0)
895 (setq frame (next-frame frame))
896 (while (not (eq (frame-visible-p frame) t))
897 (setq frame (next-frame frame)))
898 (setq arg (1- arg)))
899 (while (< arg 0)
900 (setq frame (previous-frame frame))
901 (while (not (eq (frame-visible-p frame) t))
902 (setq frame (previous-frame frame)))
903 (setq arg (1+ arg)))
904 (select-frame-set-input-focus frame)))
905
906(defun iconify-or-deiconify-frame ()
907 "Iconify the selected frame, or deiconify if it's currently an icon."
908 (interactive)
909 (if (eq (cdr (assq 'visibility (frame-parameters))) t)
910 (iconify-frame)
911 (make-frame-visible)))
912
913(defun suspend-frame ()
914 "Do whatever is right to suspend the current frame.
915Calls `suspend-emacs' if invoked from the controlling tty device,
916`suspend-tty' from a secondary tty device, and
917`iconify-or-deiconify-frame' from an X frame."
918 (interactive)
919 (let ((type (framep (selected-frame))))
920 (cond
921 ((memq type '(x ns w32)) (iconify-or-deiconify-frame))
922 ((eq type t)
923 (if (controlling-tty-p)
924 (suspend-emacs)
925 (suspend-tty)))
926 (t (suspend-emacs)))))
927
928(defun make-frame-names-alist ()
929 (let* ((current-frame (selected-frame))
930 (falist
931 (cons
932 (cons (frame-parameter current-frame 'name) current-frame) nil))
933 (frame (next-frame nil t)))
934 (while (not (eq frame current-frame))
935 (progn
936 (setq falist (cons (cons (frame-parameter frame 'name) frame) falist))
937 (setq frame (next-frame frame t))))
938 falist))
939
940(defvar frame-name-history nil)
941(defun select-frame-by-name (name)
942 "Select the frame on the current terminal whose name is NAME and raise it.
943If there is no frame by that name, signal an error."
944 (interactive
945 (let* ((frame-names-alist (make-frame-names-alist))
946 (default (car (car frame-names-alist)))
947 (input (completing-read
948 (format "Select Frame (default %s): " default)
949 frame-names-alist nil t nil 'frame-name-history)))
950 (if (= (length input) 0)
951 (list default)
952 (list input))))
953 (let* ((frame-names-alist (make-frame-names-alist))
954 (frame (cdr (assoc name frame-names-alist))))
955 (if frame
956 (select-frame-set-input-focus frame)
957 (error "There is no frame named `%s'" name))))
958\f
959;;;; Frame configurations
960
961(defun current-frame-configuration ()
962 "Return a list describing the positions and states of all frames.
963Its car is `frame-configuration'.
964Each element of the cdr is a list of the form (FRAME ALIST WINDOW-CONFIG),
965where
966 FRAME is a frame object,
967 ALIST is an association list specifying some of FRAME's parameters, and
968 WINDOW-CONFIG is a window configuration object for FRAME."
969 (cons 'frame-configuration
970 (mapcar (lambda (frame)
971 (list frame
972 (frame-parameters frame)
973 (current-window-configuration frame)))
974 (frame-list))))
975
976(defun set-frame-configuration (configuration &optional nodelete)
977 "Restore the frames to the state described by CONFIGURATION.
978Each frame listed in CONFIGURATION has its position, size, window
979configuration, and other parameters set as specified in CONFIGURATION.
980However, this function does not restore deleted frames.
981
982Ordinarily, this function deletes all existing frames not
983listed in CONFIGURATION. But if optional second argument NODELETE
984is given and non-nil, the unwanted frames are iconified instead."
985 (or (frame-configuration-p configuration)
986 (signal 'wrong-type-argument
987 (list 'frame-configuration-p configuration)))
988 (let ((config-alist (cdr configuration))
989 frames-to-delete)
990 (dolist (frame (frame-list))
991 (let ((parameters (assq frame config-alist)))
992 (if parameters
993 (progn
994 (modify-frame-parameters
995 frame
996 ;; Since we can't set a frame's minibuffer status,
997 ;; we might as well omit the parameter altogether.
998 (let* ((parms (nth 1 parameters))
999 (mini (assq 'minibuffer parms))
1000 (name (assq 'name parms))
1001 (explicit-name (cdr (assq 'explicit-name parms))))
1002 (when mini (setq parms (delq mini parms)))
1003 ;; Leave name in iff it was set explicitly.
1004 ;; This should fix the behavior reported in
1005 ;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg01632.html
1006 (when (and name (not explicit-name))
1007 (setq parms (delq name parms)))
1008 parms))
1009 (set-window-configuration (nth 2 parameters)))
1010 (setq frames-to-delete (cons frame frames-to-delete)))))
1011 (mapc (if nodelete
1012 ;; Note: making frames invisible here was tried
1013 ;; but led to some strange behavior--each time the frame
1014 ;; was made visible again, the window manager asked afresh
1015 ;; for where to put it.
1016 'iconify-frame
1017 'delete-frame)
1018 frames-to-delete)))
1019\f
1020;;;; Convenience functions for accessing and interactively changing
1021;;;; frame parameters.
1022
1023(defun frame-height (&optional frame)
1024 "Return number of lines available for display on FRAME.
1025If FRAME is omitted, describe the currently selected frame."
1026 (cdr (assq 'height (frame-parameters frame))))
1027
1028(defun frame-width (&optional frame)
1029 "Return number of columns available for display on FRAME.
1030If FRAME is omitted, describe the currently selected frame."
1031 (cdr (assq 'width (frame-parameters frame))))
1032
1033(declare-function x-list-fonts "xfaces.c"
1034 (pattern &optional face frame maximum width))
1035
1036(define-obsolete-function-alias 'set-default-font 'set-frame-font "23.1")
1037(defun set-frame-font (font-name &optional keep-size)
1038 "Set the font of the selected frame to FONT-NAME.
1039When called interactively, prompt for the name of the font to use.
1040To get the frame's current default font, use `frame-parameters'.
1041
1042The default behavior is to keep the numbers of lines and columns in
1043the frame, thus may change its pixel size. If optional KEEP-SIZE is
1044non-nil (interactively, prefix argument) the current frame size (in
1045pixels) is kept by adjusting the numbers of the lines and columns."
1046 (interactive
1047 (let* ((completion-ignore-case t)
1048 (font (completing-read "Font name: "
1049 ;; x-list-fonts will fail with an error
1050 ;; if this frame doesn't support fonts.
1051 (x-list-fonts "*" nil (selected-frame))
1052 nil nil nil nil
1053 (frame-parameter nil 'font))))
1054 (list font current-prefix-arg)))
1055 (let (fht fwd)
1056 (if keep-size
1057 (setq fht (* (frame-parameter nil 'height) (frame-char-height))
1058 fwd (* (frame-parameter nil 'width) (frame-char-width))))
1059 (modify-frame-parameters (selected-frame)
1060 (list (cons 'font font-name)))
1061 (if keep-size
1062 (modify-frame-parameters
1063 (selected-frame)
1064 (list (cons 'height (round fht (frame-char-height)))
1065 (cons 'width (round fwd (frame-char-width)))))))
1066 (run-hooks 'after-setting-font-hook 'after-setting-font-hooks))
1067
1068(defun set-frame-parameter (frame parameter value)
1069 "Set frame parameter PARAMETER to VALUE on FRAME.
1070If FRAME is nil, it defaults to the selected frame.
1071See `modify-frame-parameters'."
1072 (modify-frame-parameters frame (list (cons parameter value))))
1073
1074(defun set-background-color (color-name)
1075 "Set the background color of the selected frame to COLOR-NAME.
1076When called interactively, prompt for the name of the color to use.
1077To get the frame's current background color, use `frame-parameters'."
1078 (interactive (list (facemenu-read-color "Background color: ")))
1079 (modify-frame-parameters (selected-frame)
1080 (list (cons 'background-color color-name)))
1081 (or window-system
1082 (face-set-after-frame-default (selected-frame))))
1083
1084(defun set-foreground-color (color-name)
1085 "Set the foreground color of the selected frame to COLOR-NAME.
1086When called interactively, prompt for the name of the color to use.
1087To get the frame's current foreground color, use `frame-parameters'."
1088 (interactive (list (facemenu-read-color "Foreground color: ")))
1089 (modify-frame-parameters (selected-frame)
1090 (list (cons 'foreground-color color-name)))
1091 (or window-system
1092 (face-set-after-frame-default (selected-frame))))
1093
1094(defun set-cursor-color (color-name)
1095 "Set the text cursor color of the selected frame to COLOR-NAME.
1096When called interactively, prompt for the name of the color to use.
1097To get the frame's current cursor color, use `frame-parameters'."
1098 (interactive (list (facemenu-read-color "Cursor color: ")))
1099 (modify-frame-parameters (selected-frame)
1100 (list (cons 'cursor-color color-name))))
1101
1102(defun set-mouse-color (color-name)
1103 "Set the color of the mouse pointer of the selected frame to COLOR-NAME.
1104When called interactively, prompt for the name of the color to use.
1105To get the frame's current mouse color, use `frame-parameters'."
1106 (interactive (list (facemenu-read-color "Mouse color: ")))
1107 (modify-frame-parameters (selected-frame)
1108 (list (cons 'mouse-color
1109 (or color-name
1110 (cdr (assq 'mouse-color
1111 (frame-parameters))))))))
1112
1113(defun set-border-color (color-name)
1114 "Set the color of the border of the selected frame to COLOR-NAME.
1115When called interactively, prompt for the name of the color to use.
1116To get the frame's current border color, use `frame-parameters'."
1117 (interactive (list (facemenu-read-color "Border color: ")))
1118 (modify-frame-parameters (selected-frame)
1119 (list (cons 'border-color color-name))))
1120
1121(defun auto-raise-mode (arg)
1122 "Toggle whether or not the selected frame should auto-raise.
1123With ARG, turn auto-raise mode on if and only if ARG is positive.
1124Note that this controls Emacs's own auto-raise feature.
1125Some window managers allow you to enable auto-raise for certain windows.
1126You can use that for Emacs windows if you wish, but if you do,
1127that is beyond the control of Emacs and this command has no effect on it."
1128 (interactive "P")
1129 (if (null arg)
1130 (setq arg
1131 (if (cdr (assq 'auto-raise (frame-parameters (selected-frame))))
1132 -1 1)))
1133 (if (> arg 0)
1134 (raise-frame (selected-frame)))
1135 (modify-frame-parameters (selected-frame)
1136 (list (cons 'auto-raise (> arg 0)))))
1137
1138(defun auto-lower-mode (arg)
1139 "Toggle whether or not the selected frame should auto-lower.
1140With ARG, turn auto-lower mode on if and only if ARG is positive.
1141Note that this controls Emacs's own auto-lower feature.
1142Some window managers allow you to enable auto-lower for certain windows.
1143You can use that for Emacs windows if you wish, but if you do,
1144that is beyond the control of Emacs and this command has no effect on it."
1145 (interactive "P")
1146 (if (null arg)
1147 (setq arg
1148 (if (cdr (assq 'auto-lower (frame-parameters (selected-frame))))
1149 -1 1)))
1150 (modify-frame-parameters (selected-frame)
1151 (list (cons 'auto-lower (> arg 0)))))
1152(defun set-frame-name (name)
1153 "Set the name of the selected frame to NAME.
1154When called interactively, prompt for the name of the frame.
1155The frame name is displayed on the modeline if the terminal displays only
1156one frame, otherwise the name is displayed on the frame's caption bar."
1157 (interactive "sFrame name: ")
1158 (modify-frame-parameters (selected-frame)
1159 (list (cons 'name name))))
1160
1161(defun frame-current-scroll-bars (&optional frame)
1162 "Return the current scroll-bar settings in frame FRAME.
1163Value is a cons (VERTICAL . HORIZ0NTAL) where VERTICAL specifies the
1164current location of the vertical scroll-bars (left, right, or nil),
1165and HORIZONTAL specifies the current location of the horizontal scroll
1166bars (top, bottom, or nil)."
1167 (let ((vert (frame-parameter frame 'vertical-scroll-bars))
1168 (hor nil))
1169 (unless (memq vert '(left right nil))
1170 (setq vert default-frame-scroll-bars))
1171 (cons vert hor)))
1172\f
1173;;;; Frame/display capabilities.
1174(defun selected-terminal ()
1175 "Return the terminal that is now selected."
1176 (frame-terminal (selected-frame)))
1177
1178(declare-function msdos-mouse-p "dosfns.c")
1179
1180(defun display-mouse-p (&optional display)
1181 "Return non-nil if DISPLAY has a mouse available.
1182DISPLAY can be a display name, a frame, or nil (meaning the selected
1183frame's display)."
1184 (let ((frame-type (framep-on-display display)))
1185 (cond
1186 ((eq frame-type 'pc)
1187 (msdos-mouse-p))
1188 ((eq system-type 'windows-nt)
1189 (with-no-warnings
1190 (> w32-num-mouse-buttons 0)))
1191 ((memq frame-type '(x ns))
1192 t) ;; We assume X and NeXTstep *always* have a pointing device
1193 (t
1194 (or (and (featurep 'xt-mouse)
1195 xterm-mouse-mode)
1196 ;; t-mouse is distributed with the GPM package. It doesn't have
1197 ;; a toggle.
1198 (featurep 't-mouse))))))
1199
1200(defun display-popup-menus-p (&optional display)
1201 "Return non-nil if popup menus are supported on DISPLAY.
1202DISPLAY can be a display name, a frame, or nil (meaning the selected
1203frame's display).
1204Support for popup menus requires that the mouse be available."
1205 (and
1206 (let ((frame-type (framep-on-display display)))
1207 (memq frame-type '(x w32 pc ns)))
1208 (display-mouse-p display)))
1209
1210(defun display-graphic-p (&optional display)
1211 "Return non-nil if DISPLAY is a graphic display.
1212Graphical displays are those which are capable of displaying several
1213frames and several different fonts at once. This is true for displays
1214that use a window system such as X, and false for text-only terminals.
1215DISPLAY can be a display name, a frame, or nil (meaning the selected
1216frame's display)."
1217 (not (null (memq (framep-on-display display) '(x w32 ns)))))
1218
1219(defun display-images-p (&optional display)
1220 "Return non-nil if DISPLAY can display images.
1221
1222DISPLAY can be a display name, a frame, or nil (meaning the selected
1223frame's display)."
1224 (and (display-graphic-p display)
1225 (fboundp 'image-mask-p)
1226 (fboundp 'image-size)))
1227
1228(defalias 'display-multi-frame-p 'display-graphic-p)
1229(defalias 'display-multi-font-p 'display-graphic-p)
1230
1231(defun display-selections-p (&optional display)
1232 "Return non-nil if DISPLAY supports selections.
1233A selection is a way to transfer text or other data between programs
1234via special system buffers called `selection' or `cut buffer' or
1235`clipboard'.
1236DISPLAY can be a display name, a frame, or nil (meaning the selected
1237frame's display)."
1238 (let ((frame-type (framep-on-display display)))
1239 (cond
1240 ((eq frame-type 'pc)
1241 ;; MS-DOG frames support selections when Emacs runs inside
1242 ;; the Windows' DOS Box.
1243 (with-no-warnings
1244 (not (null dos-windows-version))))
1245 ((memq frame-type '(x w32 ns))
1246 t) ;; FIXME?
1247 (t
1248 nil))))
1249
1250(declare-function x-display-screens "xfns.c" (&optional terminal))
1251
1252(defun display-screens (&optional display)
1253 "Return the number of screens associated with DISPLAY."
1254 (let ((frame-type (framep-on-display display)))
1255 (cond
1256 ((memq frame-type '(x w32 ns))
1257 (x-display-screens display))
1258 (t
1259 1))))
1260
1261(declare-function x-display-pixel-height "xfns.c" (&optional terminal))
1262
1263(defun display-pixel-height (&optional display)
1264 "Return the height of DISPLAY's screen in pixels.
1265For character terminals, each character counts as a single pixel."
1266 (let ((frame-type (framep-on-display display)))
1267 (cond
1268 ((memq frame-type '(x w32 ns))
1269 (x-display-pixel-height display))
1270 (t
1271 (frame-height (if (framep display) display (selected-frame)))))))
1272
1273(declare-function x-display-pixel-width "xfns.c" (&optional terminal))
1274
1275(defun display-pixel-width (&optional display)
1276 "Return the width of DISPLAY's screen in pixels.
1277For character terminals, each character counts as a single pixel."
1278 (let ((frame-type (framep-on-display display)))
1279 (cond
1280 ((memq frame-type '(x w32 ns))
1281 (x-display-pixel-width display))
1282 (t
1283 (frame-width (if (framep display) display (selected-frame)))))))
1284
1285(defcustom display-mm-dimensions-alist nil
1286 "Alist for specifying screen dimensions in millimeters.
1287The dimensions will be used for `display-mm-height' and
1288`display-mm-width' if defined for the respective display.
1289
1290Each element of the alist has the form (display . (width . height)),
1291e.g. (\":0.0\" . (287 . 215)).
1292
1293If `display' equals t, it specifies dimensions for all graphical
1294displays not explicitely specified."
1295 :version "22.1"
1296 :type '(alist :key-type (choice (string :tag "Display name")
1297 (const :tag "Default" t))
1298 :value-type (cons :tag "Dimensions"
1299 (integer :tag "Width")
1300 (integer :tag "Height")))
1301 :group 'frames)
1302
1303(declare-function x-display-mm-height "xfns.c" (&optional terminal))
1304
1305(defun display-mm-height (&optional display)
1306 "Return the height of DISPLAY's screen in millimeters.
1307System values can be overridden by `display-mm-dimensions-alist'.
1308If the information is unavailable, value is nil."
1309 (and (memq (framep-on-display display) '(x w32 ns))
1310 (or (cddr (assoc (or display (frame-parameter nil 'display))
1311 display-mm-dimensions-alist))
1312 (cddr (assoc t display-mm-dimensions-alist))
1313 (x-display-mm-height display))))
1314
1315(declare-function x-display-mm-width "xfns.c" (&optional terminal))
1316
1317(defun display-mm-width (&optional display)
1318 "Return the width of DISPLAY's screen in millimeters.
1319System values can be overridden by `display-mm-dimensions-alist'.
1320If the information is unavailable, value is nil."
1321 (and (memq (framep-on-display display) '(x w32 ns))
1322 (or (cadr (assoc (or display (frame-parameter nil 'display))
1323 display-mm-dimensions-alist))
1324 (cadr (assoc t display-mm-dimensions-alist))
1325 (x-display-mm-width display))))
1326
1327(declare-function x-display-backing-store "xfns.c" (&optional terminal))
1328
1329(defun display-backing-store (&optional display)
1330 "Return the backing store capability of DISPLAY's screen.
1331The value may be `always', `when-mapped', `not-useful', or nil if
1332the question is inapplicable to a certain kind of display."
1333 (let ((frame-type (framep-on-display display)))
1334 (cond
1335 ((memq frame-type '(x w32 ns))
1336 (x-display-backing-store display))
1337 (t
1338 'not-useful))))
1339
1340(declare-function x-display-save-under "xfns.c" (&optional terminal))
1341
1342(defun display-save-under (&optional display)
1343 "Return non-nil if DISPLAY's screen supports the SaveUnder feature."
1344 (let ((frame-type (framep-on-display display)))
1345 (cond
1346 ((memq frame-type '(x w32 ns))
1347 (x-display-save-under display))
1348 (t
1349 'not-useful))))
1350
1351(declare-function x-display-planes "xfns.c" (&optional terminal))
1352
1353(defun display-planes (&optional display)
1354 "Return the number of planes supported by DISPLAY."
1355 (let ((frame-type (framep-on-display display)))
1356 (cond
1357 ((memq frame-type '(x w32 ns))
1358 (x-display-planes display))
1359 ((eq frame-type 'pc)
1360 4)
1361 (t
1362 (truncate (log (length (tty-color-alist)) 2))))))
1363
1364(declare-function x-display-color-cells "xfns.c" (&optional terminal))
1365
1366(defun display-color-cells (&optional display)
1367 "Return the number of color cells supported by DISPLAY."
1368 (let ((frame-type (framep-on-display display)))
1369 (cond
1370 ((memq frame-type '(x w32 ns))
1371 (x-display-color-cells display))
1372 ((eq frame-type 'pc)
1373 16)
1374 (t
1375 (tty-display-color-cells display)))))
1376
1377(declare-function x-display-visual-class "xfns.c" (&optional terminal))
1378
1379(defun display-visual-class (&optional display)
1380 "Return the visual class of DISPLAY.
1381The value is one of the symbols `static-gray', `gray-scale',
1382`static-color', `pseudo-color', `true-color', or `direct-color'."
1383 (let ((frame-type (framep-on-display display)))
1384 (cond
1385 ((memq frame-type '(x w32 ns))
1386 (x-display-visual-class display))
1387 ((and (memq frame-type '(pc t))
1388 (tty-display-color-p display))
1389 'static-color)
1390 (t
1391 'static-gray))))
1392
1393\f
1394;;;; Frame geometry values
1395
1396(defun frame-geom-value-cons (type value &optional frame)
1397 "Return equivalent geometry value for FRAME as a cons with car `+'.
1398A geometry value equivalent to VALUE for FRAME is returned,
1399where the value is a cons with car `+', not numeric.
1400TYPE is the car of the original geometry spec (TYPE . VALUE).
1401 It is `top' or `left', depending on which edge VALUE is related to.
1402VALUE is the cdr of a frame geometry spec: (left/top . VALUE).
1403If VALUE is a number, then it is converted to a cons value, perhaps
1404 relative to the opposite frame edge from that in the original spec.
1405FRAME defaults to the selected frame.
1406
1407Examples (measures in pixels) -
1408 Assuming display height/width=1024, frame height/width=600:
1409 300 inside display edge: 300 => (+ 300)
1410 (+ 300) => (+ 300)
1411 300 inside opposite display edge: (- 300) => (+ 124)
1412 -300 => (+ 124)
1413 300 beyond display edge
1414 (= 724 inside opposite display edge): (+ -300) => (+ -300)
1415 300 beyond display edge
1416 (= 724 inside opposite display edge): (- -300) => (+ 724)
1417
1418In the 3rd, 4th, and 6th examples, the returned value is relative to
1419the opposite frame edge from the edge indicated in the input spec."
1420 (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300)
1421 value)
1422 ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300)
1423 (t ; e.g. -300, (- 300), (- -300)
1424 (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724)
1425 (x-display-pixel-width)
1426 (x-display-pixel-height))
1427 (if (integerp value) (- value) (cadr value))
1428 (if (eq 'left type)
1429 (frame-pixel-width frame)
1430 (frame-pixel-height frame)))))))
1431
1432(defun frame-geom-spec-cons (spec &optional frame)
1433 "Return equivalent geometry spec for FRAME as a cons with car `+'.
1434A geometry specification equivalent to SPEC for FRAME is returned,
1435where the value is a cons with car `+', not numeric.
1436SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE).
1437If VALUE is a number, then it is converted to a cons value, perhaps
1438 relative to the opposite frame edge from that in the original spec.
1439FRAME defaults to the selected frame.
1440
1441Examples (measures in pixels) -
1442 Assuming display height=1024, frame height=600:
1443 top 300 below display top: (top . 300) => (top + 300)
1444 (top + 300) => (top + 300)
1445 bottom 300 above display bottom: (top - 300) => (top + 124)
1446 (top . -300) => (top + 124)
1447 top 300 above display top
1448 (= bottom 724 above display bottom): (top + -300) => (top + -300)
1449 bottom 300 below display bottom
1450 (= top 724 below display top): (top - -300) => (top + 724)
1451
1452In the 3rd, 4th, and 6th examples, the returned value is relative to
1453the opposite frame edge from the edge indicated in the input spec."
1454 (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec))))
1455\f
1456;;;; Aliases for backward compatibility with Emacs 18.
1457(define-obsolete-function-alias 'screen-height 'frame-height "19.7")
1458(define-obsolete-function-alias 'screen-width 'frame-width "19.7")
1459
1460(defun set-screen-width (cols &optional pretend)
1461 "Change the size of the screen to COLS columns.
1462Optional second arg non-nil means that redisplay should use COLS columns
1463but that the idea of the actual width of the frame should not be changed.
1464This function is provided only for compatibility with Emacs 18."
1465 (set-frame-width (selected-frame) cols pretend))
1466
1467(defun set-screen-height (lines &optional pretend)
1468 "Change the height of the screen to LINES lines.
1469Optional second arg non-nil means that redisplay should use LINES lines
1470but that the idea of the actual height of the screen should not be changed.
1471This function is provided only for compatibility with Emacs 18."
1472 (set-frame-height (selected-frame) lines pretend))
1473
1474(defun delete-other-frames (&optional frame)
1475 "Delete all frames except FRAME.
1476If FRAME uses another frame's minibuffer, the minibuffer frame is
1477left untouched. FRAME nil or omitted means use the selected frame."
1478 (interactive)
1479 (unless frame
1480 (setq frame (selected-frame)))
1481 (let* ((mini-frame (window-frame (minibuffer-window frame)))
1482 (frames (delq mini-frame (delq frame (frame-list)))))
1483 ;; Delete mon-minibuffer-only frames first, because `delete-frame'
1484 ;; signals an error when trying to delete a mini-frame that's
1485 ;; still in use by another frame.
1486 (dolist (frame frames)
1487 (unless (eq (frame-parameter frame 'minibuffer) 'only)
1488 (delete-frame frame)))
1489 ;; Delete minibuffer-only frames.
1490 (dolist (frame frames)
1491 (when (eq (frame-parameter frame 'minibuffer) 'only)
1492 (delete-frame frame)))))
1493
1494(make-obsolete 'set-screen-width 'set-frame-width "19.7")
1495(make-obsolete 'set-screen-height 'set-frame-height "19.7")
1496
1497;; miscellaneous obsolescence declarations
1498(define-obsolete-variable-alias 'delete-frame-hook
1499 'delete-frame-functions "22.1")
1500
1501\f
1502;; Highlighting trailing whitespace.
1503
1504(make-variable-buffer-local 'show-trailing-whitespace)
1505
1506(defcustom show-trailing-whitespace nil
1507 "Non-nil means highlight trailing whitespace.
1508This is done in the face `trailing-whitespace'."
1509 :type 'boolean
1510 :group 'whitespace-faces)
1511
1512
1513\f
1514;; Scrolling
1515
1516(defgroup scrolling nil
1517 "Scrolling windows."
1518 :version "21.1"
1519 :group 'frames)
1520
1521(defcustom auto-hscroll-mode t
1522 "Allow or disallow automatic scrolling windows horizontally.
1523If non-nil, windows are automatically scrolled horizontally to make
1524point visible."
1525 :version "21.1"
1526 :type 'boolean
1527 :group 'scrolling)
1528(defvaralias 'automatic-hscrolling 'auto-hscroll-mode)
1529
1530\f
1531;; Blinking cursor
1532
1533(defgroup cursor nil
1534 "Displaying text cursors."
1535 :version "21.1"
1536 :group 'frames)
1537
1538(defcustom blink-cursor-delay 0.5
1539 "Seconds of idle time after which cursor starts to blink."
1540 :type 'number
1541 :group 'cursor)
1542
1543(defcustom blink-cursor-interval 0.5
1544 "Length of cursor blink interval in seconds."
1545 :type 'number
1546 :group 'cursor)
1547
1548(defvar blink-cursor-idle-timer nil
1549 "Timer started after `blink-cursor-delay' seconds of Emacs idle time.
1550The function `blink-cursor-start' is called when the timer fires.")
1551
1552(defvar blink-cursor-timer nil
1553 "Timer started from `blink-cursor-start'.
1554This timer calls `blink-cursor-timer-function' every
1555`blink-cursor-interval' seconds.")
1556
1557(defun blink-cursor-start ()
1558 "Timer function called from the timer `blink-cursor-idle-timer'.
1559This starts the timer `blink-cursor-timer', which makes the cursor blink
1560if appropriate. It also arranges to cancel that timer when the next
1561command starts, by installing a pre-command hook."
1562 (when (null blink-cursor-timer)
1563 ;; Set up the timer first, so that if this signals an error,
1564 ;; blink-cursor-end is not added to pre-command-hook.
1565 (setq blink-cursor-timer
1566 (run-with-timer blink-cursor-interval blink-cursor-interval
1567 'blink-cursor-timer-function))
1568 (add-hook 'pre-command-hook 'blink-cursor-end)
1569 (internal-show-cursor nil nil)))
1570
1571(defun blink-cursor-timer-function ()
1572 "Timer function of timer `blink-cursor-timer'."
1573 (internal-show-cursor nil (not (internal-show-cursor-p))))
1574
1575(defun blink-cursor-end ()
1576 "Stop cursor blinking.
1577This is installed as a pre-command hook by `blink-cursor-start'.
1578When run, it cancels the timer `blink-cursor-timer' and removes
1579itself as a pre-command hook."
1580 (remove-hook 'pre-command-hook 'blink-cursor-end)
1581 (internal-show-cursor nil t)
1582 (when blink-cursor-timer
1583 (cancel-timer blink-cursor-timer)
1584 (setq blink-cursor-timer nil)))
1585
1586(define-minor-mode blink-cursor-mode
1587 "Toggle blinking cursor mode.
1588With a numeric argument, turn blinking cursor mode on if ARG is positive,
1589otherwise turn it off. When blinking cursor mode is enabled, the
1590cursor of the selected window blinks.
1591
1592Note that this command is effective only when Emacs
1593displays through a window system, because then Emacs does its own
1594cursor display. On a text-only terminal, this is not implemented."
1595 :init-value (not (or noninteractive
1596 no-blinking-cursor
1597 (eq system-type 'ms-dos)
1598 (not (memq window-system '(x w32)))))
1599 :initialize 'custom-initialize-safe-default
1600 :group 'cursor
1601 :global t
1602 (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer))
1603 (setq blink-cursor-idle-timer nil)
1604 (blink-cursor-end)
1605 (when blink-cursor-mode
1606 ;; Hide the cursor.
1607 ;;(internal-show-cursor nil nil)
1608 (setq blink-cursor-idle-timer
1609 (run-with-idle-timer blink-cursor-delay
1610 blink-cursor-delay
1611 'blink-cursor-start))))
1612
1613(define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1")
1614\f
1615;; Hourglass pointer
1616
1617(defcustom display-hourglass t
1618 "Non-nil means show an hourglass pointer, when Emacs is busy.
1619This feature only works when on a window system that can change
1620cursor shapes."
1621 :type 'boolean
1622 :group 'cursor)
1623
1624(defcustom hourglass-delay 1
1625 "Seconds to wait before displaying an hourglass pointer when Emacs is busy."
1626 :type 'number
1627 :group 'cursor)
1628
1629\f
1630(defcustom cursor-in-non-selected-windows t
1631 "Non-nil means show a hollow box cursor in non-selected windows.
1632If nil, don't show a cursor except in the selected window.
1633If t, display a cursor related to the usual cursor type
1634 \(a solid box becomes hollow, a bar becomes a narrower bar).
1635You can also specify the cursor type as in the `cursor-type' variable.
1636Use Custom to set this variable to get the display updated."
1637 :tag "Cursor In Non-selected Windows"
1638 :type 'boolean
1639 :group 'cursor
1640 :set #'(lambda (symbol value)
1641 (set-default symbol value)
1642 (force-mode-line-update t)))
1643
1644\f
1645;;;; Key bindings
1646
1647(define-key ctl-x-5-map "2" 'make-frame-command)
1648(define-key ctl-x-5-map "1" 'delete-other-frames)
1649(define-key ctl-x-5-map "0" 'delete-frame)
1650(define-key ctl-x-5-map "o" 'other-frame)
1651
1652(provide 'frame)
1653
1654;; arch-tag: 82979c70-b8f2-4306-b2ad-ddbd6b328b56
1655;;; frame.el ends here