(custom-facep): Defined (once again).
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
fa54c6ae 2 Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation.
dc6f92b8
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
1113d9db 8the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
dc6f92b8 20
18160b98 21#include <config.h>
565620a5
RS
22
23#include <stdio.h>
cc38027b 24#include "lisp.h"
71025e5e
KH
25#include "charset.h"
26#ifdef HAVE_WINDOW_SYSTEM
27#include "fontset.h"
28#endif
cc38027b 29#include "frame.h"
bc1ed486 30#include "termhooks.h"
f769f1b2 31#include "window.h"
87485d6f
MW
32#ifdef MSDOS
33#include "msdos.h"
34#endif
e5d77022 35
fd0c2bd1
JB
36/* Evaluate this expression to rebuild the section of syms_of_frame
37 that initializes and staticpros the symbols declared below. Note
38 that Emacs 18 has a bug that keeps C-x C-e from being able to
39 evaluate this expression.
40
41(progn
42 ;; Accumulate a list of the symbols we want to initialize from the
43 ;; declarations at the top of the file.
44 (goto-char (point-min))
45 (search-forward "/\*&&& symbols declared here &&&*\/\n")
46 (let (symbol-list)
47 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
48 (setq symbol-list
49 (cons (buffer-substring (match-beginning 1) (match-end 1))
50 symbol-list))
51 (forward-line 1))
52 (setq symbol-list (nreverse symbol-list))
53 ;; Delete the section of syms_of_... where we initialize the symbols.
54 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
55 (let ((start (point)))
56 (while (looking-at "^ Q")
57 (forward-line 2))
58 (kill-region start (point)))
59 ;; Write a new symbol initialization section.
60 (while symbol-list
61 (insert (format " %s = intern (\"" (car symbol-list)))
62 (let ((start (point)))
63 (insert (substring (car symbol-list) 1))
64 (subst-char-in-region start (point) ?_ ?-))
65 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
66 (setq symbol-list (cdr symbol-list)))))
67 */
68
69/*&&& symbols declared here &&&*/
70Lisp_Object Qframep;
dbc4e1c1 71Lisp_Object Qframe_live_p;
fd0c2bd1
JB
72Lisp_Object Qheight;
73Lisp_Object Qicon;
bc93c097 74Lisp_Object Qminibuffer;
fd0c2bd1
JB
75Lisp_Object Qmodeline;
76Lisp_Object Qname;
fd0c2bd1
JB
77Lisp_Object Qonly;
78Lisp_Object Qunsplittable;
fa8fdbf9 79Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
80Lisp_Object Qwidth;
81Lisp_Object Qx;
fbd6baed 82Lisp_Object Qw32;
bb221971 83Lisp_Object Qpc;
f7af3f7b 84Lisp_Object Qvisible;
329ca574 85Lisp_Object Qbuffer_predicate;
fa54c6ae 86Lisp_Object Qbuffer_list;
61eaa912 87Lisp_Object Qtitle;
dc6f92b8 88
a249de79 89Lisp_Object Vterminal_frame;
a1aaa23f 90Lisp_Object Vdefault_frame_alist;
a249de79
RS
91
92static void
93syms_of_frame_1 ()
94{
95 /*&&& init symbols here &&&*/
96 Qframep = intern ("framep");
97 staticpro (&Qframep);
98 Qframe_live_p = intern ("frame-live-p");
99 staticpro (&Qframe_live_p);
100 Qheight = intern ("height");
101 staticpro (&Qheight);
102 Qicon = intern ("icon");
103 staticpro (&Qicon);
104 Qminibuffer = intern ("minibuffer");
105 staticpro (&Qminibuffer);
106 Qmodeline = intern ("modeline");
107 staticpro (&Qmodeline);
108 Qname = intern ("name");
109 staticpro (&Qname);
110 Qonly = intern ("only");
111 staticpro (&Qonly);
112 Qunsplittable = intern ("unsplittable");
113 staticpro (&Qunsplittable);
114 Qmenu_bar_lines = intern ("menu-bar-lines");
115 staticpro (&Qmenu_bar_lines);
116 Qwidth = intern ("width");
117 staticpro (&Qwidth);
118 Qx = intern ("x");
119 staticpro (&Qx);
fbd6baed
GV
120 Qw32 = intern ("w32");
121 staticpro (&Qw32);
bb221971
RS
122 Qpc = intern ("pc");
123 staticpro (&Qpc);
a249de79
RS
124 Qvisible = intern ("visible");
125 staticpro (&Qvisible);
126 Qbuffer_predicate = intern ("buffer-predicate");
127 staticpro (&Qbuffer_predicate);
fa54c6ae
RS
128 Qbuffer_list = intern ("buffer-list");
129 staticpro (&Qbuffer_list);
61eaa912
RS
130 Qtitle = intern ("title");
131 staticpro (&Qtitle);
e05169e2 132
a1aaa23f
RS
133 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
134 "Alist of default values for frame creation.\n\
135These may be set in your init file, like this:\n\
136 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
137These override values given in window system configuration data,\n\
138 including X Windows' defaults database.\n\
139For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
140For values specific to the separate minibuffer frame, see\n\
141 `minibuffer-frame-alist'.\n\
142The `menu-bar-lines' element of the list controls whether new frames\n\
143 have menu bars; `menu-bar-mode' works by altering this element.");
144 Vdefault_frame_alist = Qnil;
a249de79
RS
145}
146\f
147static void
148set_menu_bar_lines_1 (window, n)
149 Lisp_Object window;
150 int n;
151{
152 struct window *w = XWINDOW (window);
153
57aeea1e 154 XSETFASTINT (w->last_modified, 0);
a249de79
RS
155 XSETFASTINT (w->top, XFASTINT (w->top) + n);
156 XSETFASTINT (w->height, XFASTINT (w->height) - n);
157
158 /* Handle just the top child in a vertical split. */
159 if (!NILP (w->vchild))
160 set_menu_bar_lines_1 (w->vchild, n);
161
162 /* Adjust all children in a horizontal split. */
163 for (window = w->hchild; !NILP (window); window = w->next)
164 {
165 w = XWINDOW (window);
166 set_menu_bar_lines_1 (window, n);
167 }
168}
169
170static void
171set_menu_bar_lines (f, value, oldval)
172 struct frame *f;
173 Lisp_Object value, oldval;
174{
175 int nlines;
176 int olines = FRAME_MENU_BAR_LINES (f);
177
178 /* Right now, menu bars don't work properly in minibuf-only frames;
179 most of the commands try to apply themselves to the minibuffer
e3678b64 180 frame itself, and get an error because you can't switch buffers
a249de79
RS
181 in or split the minibuffer window. */
182 if (FRAME_MINIBUF_ONLY_P (f))
183 return;
184
185 if (INTEGERP (value))
186 nlines = XINT (value);
187 else
188 nlines = 0;
189
57aeea1e
RS
190 if (nlines != olines)
191 {
192 windows_or_buffers_changed++;
193 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
194 FRAME_MENU_BAR_LINES (f) = nlines;
195 set_menu_bar_lines_1 (f->root_window, nlines - olines);
196 }
a249de79
RS
197}
198\f
a249de79
RS
199#include "buffer.h"
200
201/* These help us bind and responding to switch-frame events. */
202#include "commands.h"
203#include "keyboard.h"
204
205Lisp_Object Vemacs_iconified;
206Lisp_Object Vframe_list;
a249de79 207
dc6f92b8
JB
208extern Lisp_Object Vminibuffer_list;
209extern Lisp_Object get_minibuffer ();
84386599
RS
210extern Lisp_Object Fhandle_switch_frame ();
211extern Lisp_Object Fredirect_frame_focus ();
a54d3a73 212extern Lisp_Object x_get_focus_frame ();
dc6f92b8 213\f
ff11dfa1
JB
214DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
215 "Return non-nil if OBJECT is a frame.\n\
216Value is t for a termcap frame (a character-only terminal),\n\
87485d6f
MW
217`x' for an Emacs frame that is really an X window,\n\
218`pc' for a direct-write MS-DOS frame.\n\
e6b27a8f 219See also `frame-live-p'.")
f9898cc6
JB
220 (object)
221 Lisp_Object object;
dc6f92b8 222{
e35d291d 223 if (!FRAMEP (object))
dc6f92b8 224 return Qnil;
ff11dfa1 225 switch (XFRAME (object)->output_method)
dc6f92b8
JB
226 {
227 case output_termcap:
228 return Qt;
229 case output_x_window:
fd0c2bd1 230 return Qx;
fbd6baed
GV
231 case output_w32:
232 return Qw32;
bb221971
RS
233 case output_msdos_raw:
234 return Qpc;
dc6f92b8
JB
235 default:
236 abort ();
237 }
238}
239
dbc4e1c1 240DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
241 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
242Value is nil if OBJECT is not a live frame. If object is a live\n\
243frame, the return value indicates what sort of output device it is\n\
244displayed on. Value is t for a termcap frame (a character-only\n\
245terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
246 (object)
247 Lisp_Object object;
248{
ff11dfa1
JB
249 return ((FRAMEP (object)
250 && FRAME_LIVE_P (XFRAME (object)))
251 ? Fframep (object)
f9898cc6
JB
252 : Qnil);
253}
254
ff11dfa1
JB
255struct frame *
256make_frame (mini_p)
dc6f92b8
JB
257 int mini_p;
258{
ff11dfa1
JB
259 Lisp_Object frame;
260 register struct frame *f;
dc6f92b8
JB
261 register Lisp_Object root_window;
262 register Lisp_Object mini_window;
36af7d69
KH
263 register struct Lisp_Vector *vec;
264 int i;
265
266 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
267 for (i = 0; i < VECSIZE (struct frame); i++)
268 XSETFASTINT (vec->contents[i], 0);
269 vec->size = VECSIZE (struct frame);
270 f = (struct frame *)vec;
271 XSETFRAME (frame, f);
ff11dfa1
JB
272
273 f->cursor_x = 0;
274 f->cursor_y = 0;
275 f->current_glyphs = 0;
276 f->desired_glyphs = 0;
277 f->visible = 0;
323405de 278 f->async_visible = 0;
7556890b 279 f->output_data.nothing = 0;
ff11dfa1 280 f->iconified = 0;
323405de 281 f->async_iconified = 0;
ff11dfa1
JB
282 f->wants_modeline = 1;
283 f->auto_raise = 0;
284 f->auto_lower = 0;
285 f->no_split = 0;
286 f->garbaged = 0;
287 f->has_minibuffer = mini_p;
a42e9724 288 f->focus_frame = Qnil;
804518aa 289 f->explicit_name = 0;
fd2777e0 290 f->can_have_scroll_bars = 0;
3a43d2dd 291 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
ff11dfa1 292 f->param_alist = Qnil;
fd2777e0
JB
293 f->scroll_bars = Qnil;
294 f->condemned_scroll_bars = Qnil;
306cc902 295 f->face_alist = Qnil;
9dd935ee 296 f->menu_bar_items = Qnil;
c8b8e7e3
RS
297 f->menu_bar_vector = Qnil;
298 f->menu_bar_items_used = 0;
329ca574 299 f->buffer_predicate = Qnil;
fa54c6ae 300 f->buffer_list = Qnil;
b4f0ee5d
KH
301#ifdef MULTI_KBOARD
302 f->kboard = initial_kboard;
303#endif
aec6e486 304 f->namebuf = 0;
2b1c9cfb 305 f->title = Qnil;
dc6f92b8 306
cc38027b 307 root_window = make_window ();
dc6f92b8
JB
308 if (mini_p)
309 {
cc38027b 310 mini_window = make_window ();
dc6f92b8
JB
311 XWINDOW (root_window)->next = mini_window;
312 XWINDOW (mini_window)->prev = root_window;
313 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
314 XWINDOW (mini_window)->frame = frame;
315 f->minibuffer_window = mini_window;
dc6f92b8
JB
316 }
317 else
318 {
319 mini_window = Qnil;
320 XWINDOW (root_window)->next = Qnil;
ff11dfa1 321 f->minibuffer_window = Qnil;
dc6f92b8
JB
322 }
323
ff11dfa1 324 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
325
326 /* 10 is arbitrary,
327 just so that there is "something there."
ff11dfa1 328 Correct size will be set up later with change_frame_size. */
dc6f92b8 329
3a43d2dd 330 SET_FRAME_WIDTH (f, 10);
ff11dfa1 331 f->height = 10;
dc6f92b8 332
f4e93c40
KH
333 XSETFASTINT (XWINDOW (root_window)->width, 10);
334 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
dc6f92b8
JB
335
336 if (mini_p)
337 {
f4e93c40
KH
338 XSETFASTINT (XWINDOW (mini_window)->width, 10);
339 XSETFASTINT (XWINDOW (mini_window)->top, 9);
340 XSETFASTINT (XWINDOW (mini_window)->height, 1);
dc6f92b8
JB
341 }
342
ff11dfa1 343 /* Choose a buffer for the frame's root window. */
5bce042c
JB
344 {
345 Lisp_Object buf;
346
347 XWINDOW (root_window)->buffer = Qt;
348 buf = Fcurrent_buffer ();
349 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
350 a space), try to find another one. */
351 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 352 buf = Fother_buffer (buf, Qnil);
5bce042c 353 Fset_window_buffer (root_window, buf);
fa54c6ae
RS
354
355 f->buffer_list = Fcons (buf, Qnil);
5bce042c
JB
356 }
357
dc6f92b8
JB
358 if (mini_p)
359 {
360 XWINDOW (mini_window)->buffer = Qt;
361 Fset_window_buffer (mini_window,
265a9e55 362 (NILP (Vminibuffer_list)
dc6f92b8
JB
363 ? get_minibuffer (0)
364 : Fcar (Vminibuffer_list)));
365 }
366
ff11dfa1
JB
367 f->root_window = root_window;
368 f->selected_window = root_window;
d5e7c279
JB
369 /* Make sure this window seems more recently used than
370 a newly-created, never-selected window. */
f4e93c40 371 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
dc6f92b8 372
71025e5e
KH
373#ifdef HAVE_WINDOW_SYSTEM
374 f->fontset_data = alloc_fontset_data ();
375#endif
376
ff11dfa1 377 return f;
dc6f92b8
JB
378}
379\f
ff11dfa1 380/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
381 MINI_WINDOW is the minibuffer window to use. nil means use the
382 default (the global minibuffer). */
383
ff11dfa1 384struct frame *
b0660239 385make_frame_without_minibuffer (mini_window, kb, display)
dc6f92b8 386 register Lisp_Object mini_window;
662ac59a 387 KBOARD *kb;
b0660239 388 Lisp_Object display;
dc6f92b8 389{
ff11dfa1 390 register struct frame *f;
363b873b 391 struct gcpro gcpro1;
dc6f92b8 392
b0660239
KH
393 if (!NILP (mini_window))
394 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8 395
662ac59a 396#ifdef MULTI_KBOARD
b0660239
KH
397 if (!NILP (mini_window)
398 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
662ac59a
KH
399 error ("frame and minibuffer must be on the same display");
400#endif
401
ff11dfa1
JB
402 /* Make a frame containing just a root window. */
403 f = make_frame (0);
dc6f92b8 404
b0660239
KH
405 if (NILP (mini_window))
406 {
407 /* Use default-minibuffer-frame if possible. */
408 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
409 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
410 {
363b873b
RS
411 Lisp_Object frame_dummy;
412
413 XSETFRAME (frame_dummy, f);
414 GCPRO1 (frame_dummy);
b0660239 415 /* If there's no minibuffer frame to use, create one. */
363b873b
RS
416 kb->Vdefault_minibuffer_frame =
417 call1 (intern ("make-initial-minibuffer-frame"), display);
418 UNGCPRO;
b0660239 419 }
363b873b 420
b0660239
KH
421 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
422 }
a2812a26 423
ff11dfa1 424 f->minibuffer_window = mini_window;
a2812a26
RS
425
426 /* Make the chosen minibuffer window display the proper minibuffer,
427 unless it is already showing a minibuffer. */
428 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
429 Fset_window_buffer (mini_window,
430 (NILP (Vminibuffer_list)
431 ? get_minibuffer (0)
432 : Fcar (Vminibuffer_list)));
ff11dfa1 433 return f;
dc6f92b8
JB
434}
435
ff11dfa1 436/* Make a frame containing only a minibuffer window. */
dc6f92b8 437
ff11dfa1
JB
438struct frame *
439make_minibuffer_frame ()
dc6f92b8 440{
ff11dfa1 441 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 442
ff11dfa1 443 register struct frame *f = make_frame (0);
dc6f92b8 444 register Lisp_Object mini_window;
ff11dfa1 445 register Lisp_Object frame;
dc6f92b8 446
2d80a27a 447 XSETFRAME (frame, f);
dc6f92b8 448
804518aa 449 f->auto_raise = 0;
ff11dfa1
JB
450 f->auto_lower = 0;
451 f->no_split = 1;
452 f->wants_modeline = 0;
453 f->has_minibuffer = 1;
dc6f92b8
JB
454
455 /* Now label the root window as also being the minibuffer.
456 Avoid infinite looping on the window chain by marking next pointer
457 as nil. */
458
ff11dfa1 459 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
460 XWINDOW (mini_window)->mini_p = Qt;
461 XWINDOW (mini_window)->next = Qnil;
804518aa 462 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 463 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
464
465 /* Put the proper buffer in that window. */
466
467 Fset_window_buffer (mini_window,
265a9e55 468 (NILP (Vminibuffer_list)
dc6f92b8
JB
469 ? get_minibuffer (0)
470 : Fcar (Vminibuffer_list)));
ff11dfa1 471 return f;
dc6f92b8
JB
472}
473\f
ff11dfa1 474/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 475
bb1513c9
RS
476static int terminal_frame_count;
477
ff11dfa1
JB
478struct frame *
479make_terminal_frame ()
dc6f92b8 480{
ff11dfa1 481 register struct frame *f;
d063751a 482 Lisp_Object frame;
bb1513c9
RS
483 char name[20];
484
b4f0ee5d
KH
485#ifdef MULTI_KBOARD
486 if (!initial_kboard)
487 {
488 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
489 init_kboard (initial_kboard);
a1b658dd
KH
490 initial_kboard->next_kboard = all_kboards;
491 all_kboards = initial_kboard;
b4f0ee5d
KH
492 }
493#endif
494
bb1513c9
RS
495 /* The first call must initialize Vframe_list. */
496 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
497 Vframe_list = Qnil;
ff11dfa1 498
ff11dfa1 499 f = make_frame (1);
d063751a 500
2d80a27a 501 XSETFRAME (frame, f);
d063751a
RS
502 Vframe_list = Fcons (frame, Vframe_list);
503
bb1513c9 504 terminal_frame_count++;
3f005256
RS
505 if (terminal_frame_count == 1)
506 {
507 f->name = build_string ("Emacs");
508 }
509 else
510 {
511 sprintf (name, "Emacs-%d", terminal_frame_count);
512 f->name = build_string (name);
513 }
bb1513c9 514
bb1513c9
RS
515 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
516 f->async_visible = 1; /* Don't let visible be cleared later. */
bb221971
RS
517#ifdef MSDOS
518 f->output_data.x = &the_only_x_display;
519 f->output_method = output_msdos_raw;
520 init_frame_faces (f);
521#else /* not MSDOS */
7556890b 522 f->output_data.nothing = 1; /* Nonzero means frame isn't deleted. */
bb221971 523#endif
ff11dfa1 524 return f;
dc6f92b8 525}
bb1513c9
RS
526
527DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
4bc7e3ad
RS
528 1, 1, 0, "Create an additional terminal frame.\n\
529You can create multiple frames on a text-only terminal in this way.\n\
530Only the selected terminal frame is actually displayed.\n\
531This function takes one argument, an alist specifying frame parameters.\n\
532In practice, generally you don't need to specify any parameters.\n\
533Note that changing the size of one terminal frame automatically affects all.")
bb1513c9
RS
534 (parms)
535 Lisp_Object parms;
536{
537 struct frame *f;
538 Lisp_Object frame;
539
541580aa 540#ifdef MSDOS
bb221971
RS
541 if (selected_frame->output_method != output_msdos_raw)
542 abort ();
543#else
bb1513c9
RS
544 if (selected_frame->output_method != output_termcap)
545 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
bb221971 546#endif
bb1513c9
RS
547
548 f = make_terminal_frame ();
549 change_frame_size (f, FRAME_HEIGHT (selected_frame),
550 FRAME_WIDTH (selected_frame), 0, 0);
551 remake_frame_glyphs (f);
552 calculate_costs (f);
553 XSETFRAME (frame, f);
8adfc1ec 554 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
bb1513c9 555 Fmodify_frame_parameters (frame, parms);
133c7a8a 556 f->face_alist = selected_frame->face_alist;
bb1513c9
RS
557 return frame;
558}
dc6f92b8 559\f
61f94483 560Lisp_Object
0aed85f4 561do_switch_frame (frame, no_enter, track)
ff11dfa1 562 Lisp_Object frame, no_enter;
0aed85f4 563 int track;
dc6f92b8 564{
2f0b07e0
JB
565 /* If FRAME is a switch-frame event, extract the frame we should
566 switch to. */
567 if (CONSP (frame)
568 && EQ (XCONS (frame)->car, Qswitch_frame)
569 && CONSP (XCONS (frame)->cdr))
570 frame = XCONS (XCONS (frame)->cdr)->car;
571
09907c3a
KH
572 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
573 a switch-frame event to arrive after a frame is no longer live,
574 especially when deleting the initial frame during startup. */
575 CHECK_FRAME (frame, 0);
576 if (! FRAME_LIVE_P (XFRAME (frame)))
577 return Qnil;
dc6f92b8 578
ff11dfa1
JB
579 if (selected_frame == XFRAME (frame))
580 return frame;
dc6f92b8 581
0aed85f4
KH
582 /* This is too greedy; it causes inappropriate focus redirection
583 that's hard to get rid of. */
584#if 0
a42e9724
JB
585 /* If a frame's focus has been redirected toward the currently
586 selected frame, we should change the redirection to point to the
587 newly selected frame. This means that if the focus is redirected
588 from a minibufferless frame to a surrogate minibuffer frame, we
589 can use `other-window' to switch between all the frames using
590 that minibuffer frame, and the focus redirection will follow us
591 around. */
0aed85f4
KH
592 if (track)
593 {
594 Lisp_Object tail;
a42e9724 595
0aed85f4
KH
596 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
597 {
598 Lisp_Object focus;
a42e9724 599
e35d291d 600 if (!FRAMEP (XCONS (tail)->car))
0aed85f4 601 abort ();
a42e9724 602
0aed85f4 603 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
a42e9724 604
e35d291d 605 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
0aed85f4
KH
606 Fredirect_frame_focus (XCONS (tail)->car, frame);
607 }
608 }
609#else /* ! 0 */
610 /* Instead, apply it only to the frame we're pointing to. */
032d78fe
GV
611#ifdef HAVE_WINDOW_SYSTEM
612 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
0aed85f4
KH
613 {
614 Lisp_Object focus, xfocus;
615
d7266360 616 xfocus = x_get_focus_frame (XFRAME (frame));
0aed85f4
KH
617 if (FRAMEP (xfocus))
618 {
619 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
620 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
621 Fredirect_frame_focus (xfocus, frame);
622 }
623 }
624#endif /* HAVE_X_WINDOWS */
625#endif /* ! 0 */
a42e9724 626
ff11dfa1
JB
627 selected_frame = XFRAME (frame);
628 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
629 last_nonminibuf_frame = selected_frame;
d5e7c279 630
ff11dfa1 631 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8 632
074577b8 633 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 634 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
635 before you take it out, make sure that evaluating something like
636 (select-window (frame-root-window (new-frame))) doesn't end up
637 with your typing being interpreted in the new frame instead of
638 the one you're actually typing in. */
ef352596 639 internal_last_event_frame = Qnil;
074577b8 640
ff11dfa1 641 return frame;
dc6f92b8
JB
642}
643
0aed85f4
KH
644DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
645 "Select the frame FRAME.\n\
646Subsequent editing commands apply to its selected window.\n\
647The selection of FRAME lasts until the next time the user does\n\
648something to select a different frame, or until the next time this\n\
649function is called.")
650 (frame, no_enter)
651 Lisp_Object frame, no_enter;
652{
653 return do_switch_frame (frame, no_enter, 1);
654}
655
656
657DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
658 "Handle a switch-frame event EVENT.\n\
659Switch-frame events are usually bound to this function.\n\
660A switch-frame event tells Emacs that the window manager has requested\n\
661that the user's events be directed to the frame mentioned in the event.\n\
662This function selects the selected window of the frame of EVENT.\n\
663\n\
664If EVENT is frame object, handle it as if it were a switch-frame event\n\
665to that frame.")
735eeca3
EN
666 (event, no_enter)
667 Lisp_Object event, no_enter;
0aed85f4 668{
6951cd71
KH
669 /* Preserve prefix arg that the command loop just cleared. */
670 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
e05169e2 671 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
735eeca3 672 return do_switch_frame (event, no_enter, 0);
0aed85f4
KH
673}
674
1c212787
KH
675DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
676 "Do nothing, but preserve any prefix argument already specified.\n\
677This is a suitable binding for iconify-frame and make-frame-visible.")
678 ()
679{
680 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
681 return Qnil;
682}
0aed85f4 683
ff11dfa1
JB
684DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
685 "Return the frame that is now selected.")
dc6f92b8
JB
686 ()
687{
688 Lisp_Object tem;
2d80a27a 689 XSETFRAME (tem, selected_frame);
dc6f92b8
JB
690 return tem;
691}
4a7cfafc 692\f
ff11dfa1
JB
693DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
694 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
695 (window)
696 Lisp_Object window;
697{
774910eb 698 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 699 return XWINDOW (window)->frame;
dc6f92b8
JB
700}
701
ba32f2db
KH
702DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
703 "Returns the topmost, leftmost window of FRAME.\n\
704If omitted, FRAME defaults to the currently selected frame.")
705 (frame)
706 Lisp_Object frame;
707{
708 Lisp_Object w;
709
710 if (NILP (frame))
711 w = selected_frame->root_window;
712 else
713 {
714 CHECK_LIVE_FRAME (frame, 0);
715 w = XFRAME (frame)->root_window;
716 }
717 while (NILP (XWINDOW (w)->buffer))
718 {
719 if (! NILP (XWINDOW (w)->hchild))
720 w = XWINDOW (w)->hchild;
721 else if (! NILP (XWINDOW (w)->vchild))
722 w = XWINDOW (w)->vchild;
723 else
724 abort ();
725 }
726 return w;
727}
728
5add3885
RS
729DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
730 Sactive_minibuffer_window, 0, 0, 0,
731 "Return the currently active minibuffer window, or nil if none.")
732 ()
733{
734 return minibuf_level ? minibuf_window : Qnil;
735}
736
ff11dfa1 737DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
738 "Returns the root-window of FRAME.\n\
739If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
740 (frame)
741 Lisp_Object frame;
dc6f92b8 742{
ff11dfa1 743 if (NILP (frame))
2d80a27a 744 XSETFRAME (frame, selected_frame);
f9898cc6 745 else
ff11dfa1 746 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 747
ff11dfa1 748 return XFRAME (frame)->root_window;
dc6f92b8
JB
749}
750
ff11dfa1
JB
751DEFUN ("frame-selected-window", Fframe_selected_window,
752 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
753 "Return the selected window of frame object FRAME.\n\
754If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
755 (frame)
756 Lisp_Object frame;
dc6f92b8 757{
ff11dfa1 758 if (NILP (frame))
2d80a27a 759 XSETFRAME (frame, selected_frame);
f9898cc6 760 else
ff11dfa1 761 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 762
ff11dfa1 763 return XFRAME (frame)->selected_window;
dc6f92b8
JB
764}
765
4a7cfafc
RS
766DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
767 Sset_frame_selected_window, 2, 2, 0,
768 "Set the selected window of frame object FRAME to WINDOW.\n\
769If FRAME is nil, the selected frame is used.\n\
770If FRAME is the selected frame, this makes WINDOW the selected window.")
771 (frame, window)
772 Lisp_Object frame, window;
773{
774 if (NILP (frame))
2d80a27a 775 XSETFRAME (frame, selected_frame);
4a7cfafc
RS
776 else
777 CHECK_LIVE_FRAME (frame, 0);
778
779 CHECK_LIVE_WINDOW (window, 1);
780
781 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
782 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
783
784 if (XFRAME (frame) == selected_frame)
785 return Fselect_window (window);
786
787 return XFRAME (frame)->selected_window = window;
788}
789\f
ff11dfa1 790DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 791 0, 0, 0,
ff11dfa1 792 "Return a list of all frames.")
dc6f92b8
JB
793 ()
794{
ff11dfa1 795 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
796}
797
ff11dfa1 798/* Return the next frame in the frame list after FRAME.
ff11dfa1 799 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
800 If MINIBUF is a window, include only its own frame
801 and any frame now using that window as the minibuffer.
f7af3f7b 802 If MINIBUF is `visible', include all visible frames.
a9986780 803 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
804 Otherwise, include all frames. */
805
dc6f92b8 806Lisp_Object
ff11dfa1
JB
807next_frame (frame, minibuf)
808 Lisp_Object frame;
f9898cc6 809 Lisp_Object minibuf;
dc6f92b8
JB
810{
811 Lisp_Object tail;
812 int passed = 0;
813
ff11dfa1
JB
814 /* There must always be at least one frame in Vframe_list. */
815 if (! CONSP (Vframe_list))
f9898cc6
JB
816 abort ();
817
dbc4e1c1
JB
818 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
819 forever. Forestall that. */
820 CHECK_LIVE_FRAME (frame, 0);
821
dc6f92b8 822 while (1)
ff11dfa1 823 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 824 {
ab9f008d 825 Lisp_Object f;
d06a8a56 826
ab9f008d 827 f = XCONS (tail)->car;
06537cc8
RS
828
829 if (passed
830 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
d5e7c279 831 {
d06a8a56
JB
832 /* Decide whether this frame is eligible to be returned. */
833
834 /* If we've looped all the way around without finding any
835 eligible frames, return the original frame. */
836 if (EQ (f, frame))
837 return f;
838
839 /* Let minibuf decide if this frame is acceptable. */
840 if (NILP (minibuf))
841 {
842 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
843 return f;
844 }
f7af3f7b
RS
845 else if (EQ (minibuf, Qvisible))
846 {
847 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
848 if (FRAME_VISIBLE_P (XFRAME (f)))
849 return f;
850 }
a9986780
RS
851 else if (XFASTINT (minibuf) == 0)
852 {
853 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
854 if (FRAME_VISIBLE_P (XFRAME (f))
855 || FRAME_ICONIFIED_P (XFRAME (f)))
856 return f;
857 }
f7af3f7b 858 else if (WINDOWP (minibuf))
d06a8a56 859 {
a9986780
RS
860 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
861 /* Check that F either is, or has forwarded its focus to,
862 MINIBUF's frame. */
863 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
864 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
865 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
866 return f;
867 }
868 else
ff11dfa1 869 return f;
d5e7c279 870 }
dc6f92b8 871
d06a8a56 872 if (EQ (frame, f))
dc6f92b8
JB
873 passed++;
874 }
875}
876
ff11dfa1 877/* Return the previous frame in the frame list before FRAME.
ff11dfa1 878 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
879 If MINIBUF is a window, include only its own frame
880 and any frame now using that window as the minibuffer.
f7af3f7b 881 If MINIBUF is `visible', include all visible frames.
a9986780 882 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
883 Otherwise, include all frames. */
884
dc6f92b8 885Lisp_Object
ff11dfa1
JB
886prev_frame (frame, minibuf)
887 Lisp_Object frame;
f9898cc6 888 Lisp_Object minibuf;
dc6f92b8
JB
889{
890 Lisp_Object tail;
891 Lisp_Object prev;
892
ff11dfa1
JB
893 /* There must always be at least one frame in Vframe_list. */
894 if (! CONSP (Vframe_list))
f9898cc6
JB
895 abort ();
896
dc6f92b8 897 prev = Qnil;
d06a8a56 898 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 899 {
ab9f008d 900 Lisp_Object f;
f9898cc6 901
ab9f008d 902 f = XCONS (tail)->car;
e35d291d 903 if (!FRAMEP (f))
d06a8a56 904 abort ();
f9898cc6 905
d06a8a56
JB
906 if (EQ (frame, f) && !NILP (prev))
907 return prev;
f9898cc6 908
06537cc8 909 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
f7af3f7b 910 {
06537cc8
RS
911 /* Decide whether this frame is eligible to be returned,
912 according to minibuf. */
913 if (NILP (minibuf))
914 {
915 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
916 prev = f;
917 }
918 else if (WINDOWP (minibuf))
919 {
920 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
921 /* Check that F either is, or has forwarded its focus to,
922 MINIBUF's frame. */
923 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
924 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
925 FRAME_FOCUS_FRAME (XFRAME (f)))))
926 prev = f;
927 }
928 else if (EQ (minibuf, Qvisible))
929 {
930 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
931 if (FRAME_VISIBLE_P (XFRAME (f)))
932 prev = f;
933 }
934 else if (XFASTINT (minibuf) == 0)
935 {
936 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
937 if (FRAME_VISIBLE_P (XFRAME (f))
938 || FRAME_ICONIFIED_P (XFRAME (f)))
939 prev = f;
940 }
941 else
a9986780
RS
942 prev = f;
943 }
f9898cc6 944 }
d06a8a56
JB
945
946 /* We've scanned the entire list. */
947 if (NILP (prev))
948 /* We went through the whole frame list without finding a single
949 acceptable frame. Return the original frame. */
950 return frame;
951 else
952 /* There were no acceptable frames in the list before FRAME; otherwise,
953 we would have returned directly from the loop. Since PREV is the last
954 acceptable frame in the list, return it. */
955 return prev;
dc6f92b8
JB
956}
957
ef2c57ac 958
ff11dfa1
JB
959DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
960 "Return the next frame in the frame list after FRAME.\n\
06537cc8 961It considers only frames on the same terminal as FRAME.\n\
a42e9724 962By default, skip minibuffer-only frames.\n\
d06a8a56 963If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 964If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 965If MINIFRAME is a window, include only its own frame\n\
a9986780 966and any frame now using that window as the minibuffer.\n\
f7af3f7b 967If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 968If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 969Otherwise, include all frames.")
ff11dfa1 970 (frame, miniframe)
8693ca83 971 Lisp_Object frame, miniframe;
dc6f92b8
JB
972{
973 Lisp_Object tail;
974
ff11dfa1 975 if (NILP (frame))
2d80a27a 976 XSETFRAME (frame, selected_frame);
f9898cc6 977 else
ff11dfa1 978 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 979
ff11dfa1 980 return next_frame (frame, miniframe);
dc6f92b8 981}
dbc4e1c1 982
ef2c57ac
RM
983DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
984 "Return the previous frame in the frame list before FRAME.\n\
06537cc8 985It considers only frames on the same terminal as FRAME.\n\
ef2c57ac
RM
986By default, skip minibuffer-only frames.\n\
987If omitted, FRAME defaults to the selected frame.\n\
988If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 989If MINIFRAME is a window, include only its own frame\n\
a9986780 990and any frame now using that window as the minibuffer.\n\
f7af3f7b 991If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 992If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 993Otherwise, include all frames.")
ef2c57ac
RM
994 (frame, miniframe)
995 Lisp_Object frame, miniframe;
996{
997 Lisp_Object tail;
998
999 if (NILP (frame))
2d80a27a 1000 XSETFRAME (frame, selected_frame);
ef2c57ac
RM
1001 else
1002 CHECK_LIVE_FRAME (frame, 0);
1003
1004 return prev_frame (frame, miniframe);
1005}
dc6f92b8 1006\f
808c0f20
RS
1007/* Return 1 if it is ok to delete frame F;
1008 0 if all frames aside from F are invisible.
1009 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1010
d56b45eb 1011int
808c0f20
RS
1012other_visible_frames (f)
1013 FRAME_PTR f;
1014{
1015 /* We know the selected frame is visible,
1016 so if F is some other frame, it can't be the sole visible one. */
1017 if (f == selected_frame)
c08c95c7
RS
1018 {
1019 Lisp_Object frames;
1020 int count = 0;
1021
1022 for (frames = Vframe_list;
1023 CONSP (frames);
1024 frames = XCONS (frames)->cdr)
1025 {
ab9f008d 1026 Lisp_Object this;
c08c95c7 1027
ab9f008d 1028 this = XCONS (frames)->car;
808c0f20
RS
1029 /* Verify that the frame's window still exists
1030 and we can still talk to it. And note any recent change
1031 in visibility. */
032d78fe
GV
1032#ifdef HAVE_WINDOW_SYSTEM
1033 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1034 {
b0509a40 1035 x_sync (XFRAME (this));
5e7b7c5b
RS
1036 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1037 }
1038#endif
1039
c08c95c7
RS
1040 if (FRAME_VISIBLE_P (XFRAME (this))
1041 || FRAME_ICONIFIED_P (XFRAME (this))
1042 /* Allow deleting the terminal frame when at least
1043 one X frame exists! */
032d78fe 1044 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1045 count++;
1046 }
808c0f20 1047 return count > 1;
c08c95c7 1048 }
808c0f20
RS
1049 return 1;
1050}
1051
1052DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1053 "Delete FRAME, permanently eliminating it from use.\n\
1054If omitted, FRAME defaults to the selected frame.\n\
1055A frame may not be deleted if its minibuffer is used by other frames.\n\
1056Normally, you may not delete a frame if all other frames are invisible,\n\
1057but if the second optional argument FORCE is non-nil, you may do so.")
1058 (frame, force)
1059 Lisp_Object frame, force;
1060{
1061 struct frame *f;
99b92e64 1062 int minibuffer_selected;
808c0f20
RS
1063
1064 if (EQ (frame, Qnil))
1065 {
1066 f = selected_frame;
2d80a27a 1067 XSETFRAME (frame, f);
808c0f20
RS
1068 }
1069 else
1070 {
1071 CHECK_FRAME (frame, 0);
1072 f = XFRAME (frame);
1073 }
1074
1075 if (! FRAME_LIVE_P (f))
1076 return Qnil;
1077
1078 if (NILP (force) && !other_visible_frames (f))
1079 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1080
ff11dfa1
JB
1081 /* Does this frame have a minibuffer, and is it the surrogate
1082 minibuffer for any other frame? */
fd0c2bd1 1083 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1084 {
ff11dfa1 1085 Lisp_Object frames;
1113d9db 1086
ff11dfa1
JB
1087 for (frames = Vframe_list;
1088 CONSP (frames);
1089 frames = XCONS (frames)->cdr)
1113d9db 1090 {
7a8cc307
RS
1091 Lisp_Object this;
1092 this = XCONS (frames)->car;
1113d9db 1093
ff11dfa1
JB
1094 if (! EQ (this, frame)
1095 && EQ (frame,
7a8cc307
RS
1096 WINDOW_FRAME (XWINDOW
1097 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 1098 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 1099 }
dc6f92b8
JB
1100 }
1101
99b92e64
RS
1102 minibuffer_selected = EQ (minibuf_window, selected_window);
1103
ff11dfa1
JB
1104 /* Don't let the frame remain selected. */
1105 if (f == selected_frame)
06537cc8
RS
1106 {
1107 Lisp_Object tail, frame1;
1108
1109 /* Look for another visible frame on the same terminal. */
1110 frame1 = next_frame (frame, Qvisible);
1111
1112 /* If there is none, find *some* other frame. */
1113 if (NILP (frame1) || EQ (frame1, frame))
1114 {
1115 FOR_EACH_FRAME (tail, frame1)
1116 {
1117 if (! EQ (frame, frame1))
1118 break;
1119 }
1120 }
1121
1122 do_switch_frame (frame1, Qnil, 0);
1123 }
dc6f92b8 1124
ff11dfa1
JB
1125 /* Don't allow minibuf_window to remain on a deleted frame. */
1126 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1127 {
ff11dfa1 1128 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1129 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1130 minibuf_window = selected_frame->minibuffer_window;
99b92e64
RS
1131
1132 /* If the dying minibuffer window was selected,
1133 select the new one. */
1134 if (minibuffer_selected)
1135 Fselect_window (minibuf_window);
dc6f92b8
JB
1136 }
1137
bb2a0a65
RS
1138 /* Clear any X selections for this frame. */
1139#ifdef HAVE_X_WINDOWS
1140 if (FRAME_X_P (f))
1141 x_clear_frame_selections (f);
1142#endif
1143
4a88b3b0
JB
1144 /* Mark all the windows that used to be on FRAME as deleted, and then
1145 remove the reference to them. */
1146 delete_all_subwindows (XWINDOW (f->root_window));
1147 f->root_window = Qnil;
1148
ff11dfa1 1149 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1150 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1151
60a8823e
KH
1152 if (f->namebuf)
1153 free (f->namebuf);
d2bee99e
RS
1154 if (FRAME_CURRENT_GLYPHS (f))
1155 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
1156 if (FRAME_DESIRED_GLYPHS (f))
1157 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
1158 if (FRAME_TEMP_GLYPHS (f))
1159 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
1160 if (FRAME_INSERT_COST (f))
1161 free (FRAME_INSERT_COST (f));
1162 if (FRAME_DELETEN_COST (f))
09d1d7e2 1163 free (FRAME_DELETEN_COST (f));
d2bee99e 1164 if (FRAME_INSERTN_COST (f))
09d1d7e2 1165 free (FRAME_INSERTN_COST (f));
d2bee99e 1166 if (FRAME_DELETE_COST (f))
09d1d7e2 1167 free (FRAME_DELETE_COST (f));
25734faf
RS
1168 if (FRAME_MESSAGE_BUF (f))
1169 free (FRAME_MESSAGE_BUF (f));
d2bee99e 1170
71025e5e
KH
1171#ifdef HAVE_WINDOW_SYSTEM
1172 /* Free all fontset data. */
1173 free_fontset_data (FRAME_FONTSET_DATA (f));
1174#endif
1175
8678b9cc
JB
1176 /* Since some events are handled at the interrupt level, we may get
1177 an event for f at any time; if we zero out the frame's display
1178 now, then we may trip up the event-handling code. Instead, we'll
1179 promise that the display of the frame must be valid until we have
1180 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
1181
1182 /* I think this should be done with a hook. */
032d78fe
GV
1183#ifdef HAVE_WINDOW_SYSTEM
1184 if (FRAME_WINDOW_P (f))
8678b9cc 1185 x_destroy_window (f);
d5e7c279
JB
1186#endif
1187
7556890b 1188 f->output_data.nothing = 0;
8678b9cc 1189
ff11dfa1 1190 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1191 another one. */
ff11dfa1 1192 if (f == last_nonminibuf_frame)
d5e7c279 1193 {
ff11dfa1 1194 Lisp_Object frames;
1113d9db 1195
ff11dfa1 1196 last_nonminibuf_frame = 0;
d5e7c279 1197
ff11dfa1
JB
1198 for (frames = Vframe_list;
1199 CONSP (frames);
1200 frames = XCONS (frames)->cdr)
d5e7c279 1201 {
ff11dfa1
JB
1202 f = XFRAME (XCONS (frames)->car);
1203 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1204 {
ff11dfa1 1205 last_nonminibuf_frame = f;
d5e7c279
JB
1206 break;
1207 }
1208 }
1209 }
dc6f92b8 1210
c4c6d073
KH
1211 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1212 find another one. Prefer minibuffer-only frames, but also notice
1213 frames with other windows. */
c60f3a6a 1214 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1113d9db 1215 {
ff11dfa1 1216 Lisp_Object frames;
1113d9db 1217
ff11dfa1 1218 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1219 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1220 /* Some frame we found on the same kboard, or nil if there are none. */
1221 Lisp_Object frame_on_same_kboard;
1113d9db 1222
32fda9ba 1223 frame_on_same_kboard = Qnil;
ab9f008d 1224 frame_with_minibuf = Qnil;
32fda9ba 1225
ff11dfa1
JB
1226 for (frames = Vframe_list;
1227 CONSP (frames);
1228 frames = XCONS (frames)->cdr)
1113d9db 1229 {
ab9f008d 1230 Lisp_Object this;
c4c6d073 1231 struct frame *f1;
1113d9db 1232
ab9f008d 1233 this = XCONS (frames)->car;
e35d291d 1234 if (!FRAMEP (this))
1113d9db 1235 abort ();
c4c6d073 1236 f1 = XFRAME (this);
1113d9db 1237
c4c6d073
KH
1238 /* Consider only frames on the same kboard
1239 and only those with minibuffers. */
1240 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1241 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1242 {
ff11dfa1 1243 frame_with_minibuf = this;
c4c6d073 1244 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1245 break;
1246 }
32fda9ba
RS
1247
1248 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1249 frame_on_same_kboard = this;
1113d9db
JB
1250 }
1251
32fda9ba
RS
1252 if (!NILP (frame_on_same_kboard))
1253 {
1254 /* We know that there must be some frame with a minibuffer out
1255 there. If this were not true, all of the frames present
1256 would have to be minibufferless, which implies that at some
1257 point their minibuffer frames must have been deleted, but
1258 that is prohibited at the top; you can't delete surrogate
1259 minibuffer frames. */
1260 if (NILP (frame_with_minibuf))
1261 abort ();
1113d9db 1262
32fda9ba
RS
1263 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1264 }
1265 else
1266 /* No frames left on this kboard--say no minibuffer either. */
1267 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1268 }
1269
e681c92a
RS
1270 /* Cause frame titles to update--necessary if we now have just one frame. */
1271 update_mode_lines = 1;
1272
dc6f92b8
JB
1273 return Qnil;
1274}
1275\f
1276/* Return mouse position in character cell units. */
1277
f9898cc6 1278DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1279 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1280The position is given in character cells, where (0, 0) is the\n\
1281upper-left corner.\n\
f9898cc6 1282If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1283to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1284and nil for X and Y.")
1285 ()
dc6f92b8 1286{
ff11dfa1 1287 FRAME_PTR f;
dbc4e1c1 1288 Lisp_Object lispy_dummy;
fd2777e0 1289 enum scroll_bar_part party_dummy;
dbc4e1c1 1290 Lisp_Object x, y;
5384466a 1291 int col, row;
dbc4e1c1 1292 unsigned long long_dummy;
dc6f92b8 1293
c5074d8c
RS
1294 f = selected_frame;
1295 x = y = Qnil;
1296
f443c170 1297#ifdef HAVE_MOUSE
c5074d8c 1298 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1299 if (mouse_position_hook)
0c5c1cf7 1300 (*mouse_position_hook) (&f, 0,
dbc4e1c1
JB
1301 &lispy_dummy, &party_dummy,
1302 &x, &y,
1303 &long_dummy);
76db7eb4
KH
1304 if (! NILP (x))
1305 {
1306 col = XINT (x);
1307 row = XINT (y);
8126c3b4 1308 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1309 XSETINT (x, col);
1310 XSETINT (y, row);
1311 }
f443c170 1312#endif
2d80a27a 1313 XSETFRAME (lispy_dummy, f);
c5074d8c 1314 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1315}
1316
152e6c70
RS
1317DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1318 Smouse_pixel_position, 0, 0, 0,
1319 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1320The position is given in pixel units, where (0, 0) is the\n\
1321upper-left corner.\n\
1322If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1323to read the mouse position, it returns the selected frame for FRAME\n\
1324and nil for X and Y.")
1325 ()
1326{
1327 FRAME_PTR f;
1328 Lisp_Object lispy_dummy;
1329 enum scroll_bar_part party_dummy;
1330 Lisp_Object x, y;
1331 int col, row;
1332 unsigned long long_dummy;
1333
1334 f = selected_frame;
1335 x = y = Qnil;
1336
0c5c1cf7 1337#ifdef HAVE_MOUSE
152e6c70
RS
1338 /* It's okay for the hook to refrain from storing anything. */
1339 if (mouse_position_hook)
0c5c1cf7 1340 (*mouse_position_hook) (&f, 0,
152e6c70
RS
1341 &lispy_dummy, &party_dummy,
1342 &x, &y,
1343 &long_dummy);
0c5c1cf7 1344#endif
2d80a27a 1345 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1346 return Fcons (lispy_dummy, Fcons (x, y));
1347}
1348
dc6f92b8 1349DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1350 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
efb57f43
RS
1351Note, this is a no-op for an X frame that is not visible.\n\
1352If you have just created a frame, you must wait for it to become visible\n\
1353before calling this function on it, like this.\n\
1354 (while (not (frame-visible-p frame)) (sleep-for .5))")
ff11dfa1
JB
1355 (frame, x, y)
1356 Lisp_Object frame, x, y;
dc6f92b8 1357{
ff11dfa1 1358 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1359 CHECK_NUMBER (x, 2);
1360 CHECK_NUMBER (y, 1);
1361
dbc4e1c1 1362 /* I think this should be done with a hook. */
032d78fe
GV
1363#ifdef HAVE_WINDOW_SYSTEM
1364 if (FRAME_WINDOW_P (XFRAME (frame)))
dc6f92b8 1365 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1366 x_set_mouse_position (XFRAME (frame), x, y);
bb221971 1367#else
be625e00 1368#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1369 if (FRAME_MSDOS_P (XFRAME (frame)))
1370 {
1371 Fselect_frame (frame, Qnil);
1372 mouse_moveto (XINT (x), XINT (y));
1373 }
1374#endif
dc6f92b8
JB
1375#endif
1376
1377 return Qnil;
1378}
152e6c70
RS
1379
1380DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1381 Sset_mouse_pixel_position, 3, 3, 0,
1382 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
efb57f43
RS
1383Note, this is a no-op for an X frame that is not visible.\n\
1384If you have just created a frame, you must wait for it to become visible\n\
1385before calling this function on it, like this.\n\
1386 (while (not (frame-visible-p frame)) (sleep-for .5))")
152e6c70
RS
1387 (frame, x, y)
1388 Lisp_Object frame, x, y;
1389{
1390 CHECK_LIVE_FRAME (frame, 0);
1391 CHECK_NUMBER (x, 2);
1392 CHECK_NUMBER (y, 1);
1393
1394 /* I think this should be done with a hook. */
032d78fe
GV
1395#ifdef HAVE_WINDOW_SYSTEM
1396 if (FRAME_WINDOW_P (XFRAME (frame)))
152e6c70
RS
1397 /* Warping the mouse will cause enternotify and focus events. */
1398 x_set_mouse_pixel_position (XFRAME (frame), x, y);
bb221971 1399#else
be625e00 1400#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1401 if (FRAME_MSDOS_P (XFRAME (frame)))
1402 {
1403 Fselect_frame (frame, Qnil);
1404 mouse_moveto (XINT (x), XINT (y));
1405 }
1406#endif
152e6c70
RS
1407#endif
1408
1409 return Qnil;
1410}
dc6f92b8 1411\f
ff11dfa1 1412DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1413 0, 1, "",
ff11dfa1 1414 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1415If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1416 (frame)
1417 Lisp_Object frame;
dc6f92b8 1418{
1aa66088 1419 if (NILP (frame))
2d80a27a 1420 XSETFRAME (frame, selected_frame);
1aa66088 1421
ff11dfa1 1422 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1423
dbc4e1c1 1424 /* I think this should be done with a hook. */
032d78fe
GV
1425#ifdef HAVE_WINDOW_SYSTEM
1426 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1427 {
1428 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1429 x_make_frame_visible (XFRAME (frame));
1430 }
fd0c2bd1 1431#endif
dc6f92b8 1432
565620a5
RS
1433 /* Make menu bar update for the Buffers and Frams menus. */
1434 windows_or_buffers_changed++;
1435
ff11dfa1 1436 return frame;
dc6f92b8
JB
1437}
1438
ff11dfa1 1439DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1440 0, 2, "",
8693ca83 1441 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1442If omitted, FRAME defaults to the currently selected frame.\n\
1443Normally you may not make FRAME invisible if all other frames are invisible,\n\
1444but if the second optional argument FORCE is non-nil, you may do so.")
1445 (frame, force)
1446 Lisp_Object frame, force;
dc6f92b8 1447{
1aa66088 1448 if (NILP (frame))
2d80a27a 1449 XSETFRAME (frame, selected_frame);
1aa66088 1450
ff11dfa1 1451 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1452
808c0f20
RS
1453 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1454 error ("Attempt to make invisible the sole visible or iconified frame");
1455
3d378fdf 1456#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1457 /* Don't let the frame remain selected. */
1458 if (XFRAME (frame) == selected_frame)
61f94483 1459 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
3d378fdf 1460#endif
9c394f17
RS
1461
1462 /* Don't allow minibuf_window to remain on a deleted frame. */
1463 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1464 {
1465 Fset_window_buffer (selected_frame->minibuffer_window,
1466 XWINDOW (minibuf_window)->buffer);
1467 minibuf_window = selected_frame->minibuffer_window;
1468 }
1469
dbc4e1c1 1470 /* I think this should be done with a hook. */
032d78fe
GV
1471#ifdef HAVE_WINDOW_SYSTEM
1472 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1473 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1474#endif
dc6f92b8 1475
565620a5
RS
1476 /* Make menu bar update for the Buffers and Frams menus. */
1477 windows_or_buffers_changed++;
1478
dc6f92b8
JB
1479 return Qnil;
1480}
1481
ff11dfa1 1482DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1483 0, 1, "",
8693ca83
JB
1484 "Make the frame FRAME into an icon.\n\
1485If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1486 (frame)
1487 Lisp_Object frame;
dc6f92b8 1488{
1aa66088 1489 if (NILP (frame))
2d80a27a 1490 XSETFRAME (frame, selected_frame);
1aa66088 1491
ff11dfa1 1492 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1493
3d378fdf 1494#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1495 /* Don't let the frame remain selected. */
1496 if (XFRAME (frame) == selected_frame)
1497 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1498#endif
9c394f17
RS
1499
1500 /* Don't allow minibuf_window to remain on a deleted frame. */
1501 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1502 {
1503 Fset_window_buffer (selected_frame->minibuffer_window,
1504 XWINDOW (minibuf_window)->buffer);
1505 minibuf_window = selected_frame->minibuffer_window;
1506 }
1507
dbc4e1c1 1508 /* I think this should be done with a hook. */
032d78fe
GV
1509#ifdef HAVE_WINDOW_SYSTEM
1510 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1511 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1512#endif
dc6f92b8 1513
565620a5
RS
1514 /* Make menu bar update for the Buffers and Frams menus. */
1515 windows_or_buffers_changed++;
1516
dc6f92b8
JB
1517 return Qnil;
1518}
1519
ff11dfa1 1520DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1521 1, 1, 0,
ff11dfa1
JB
1522 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1523A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1524a window system, it may not show at all.\n\
fd0c2bd1 1525Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1526 (frame)
1527 Lisp_Object frame;
dc6f92b8 1528{
ff11dfa1 1529 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1530
5c044f55
RS
1531 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1532
a42e9724 1533 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1534 return Qt;
a42e9724 1535 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1536 return Qicon;
dc6f92b8
JB
1537 return Qnil;
1538}
1539
ff11dfa1 1540DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1541 0, 0, 0,
ff11dfa1 1542 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1543 ()
1544{
ff11dfa1
JB
1545 Lisp_Object tail, frame;
1546 struct frame *f;
dc6f92b8
JB
1547 Lisp_Object value;
1548
1549 value = Qnil;
ff11dfa1 1550 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1551 {
ff11dfa1 1552 frame = XCONS (tail)->car;
e35d291d 1553 if (!FRAMEP (frame))
dc6f92b8 1554 continue;
ff11dfa1 1555 f = XFRAME (frame);
a42e9724 1556 if (FRAME_VISIBLE_P (f))
ff11dfa1 1557 value = Fcons (frame, value);
dc6f92b8
JB
1558 }
1559 return value;
1560}
d5e7c279
JB
1561
1562
e518d5e1 1563DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
dbc4e1c1
JB
1564 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1565If FRAME is invisible, make it visible.\n\
828ac693 1566If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1567If Emacs is displaying on an ordinary terminal or some other device which\n\
1568doesn't support multiple overlapping frames, this function does nothing.")
1569 (frame)
1570 Lisp_Object frame;
1571{
828ac693
RS
1572 if (NILP (frame))
1573 XSETFRAME (frame, selected_frame);
1574
dbc4e1c1 1575 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1576
1577 /* Do like the documentation says. */
1578 Fmake_frame_visible (frame);
1579
dbc4e1c1
JB
1580 if (frame_raise_lower_hook)
1581 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1582
1583 return Qnil;
1584}
1585
b49f5578 1586/* Should we have a corresponding function called Flower_Power? */
e518d5e1 1587DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
dbc4e1c1 1588 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1589If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1590If Emacs is displaying on an ordinary terminal or some other device which\n\
1591doesn't support multiple overlapping frames, this function does nothing.")
1592 (frame)
1593 Lisp_Object frame;
1594{
828ac693
RS
1595 if (NILP (frame))
1596 XSETFRAME (frame, selected_frame);
1597
dbc4e1c1
JB
1598 CHECK_LIVE_FRAME (frame, 0);
1599
1600 if (frame_raise_lower_hook)
1601 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1602
1603 return Qnil;
1604}
1605
d5e7c279 1606\f
ff11dfa1 1607DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1608 1, 2, 0,
ff11dfa1 1609 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1610In other words, switch-frame events caused by events in FRAME will\n\
1611request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1612FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1613\n\
a42e9724 1614If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1615cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1616\n\
a42e9724
JB
1617Focus redirection is useful for temporarily redirecting keystrokes to\n\
1618a surrogate minibuffer frame when a frame doesn't have its own\n\
1619minibuffer window.\n\
d5e7c279 1620\n\
a42e9724
JB
1621A frame's focus redirection can be changed by select-frame. If frame\n\
1622FOO is selected, and then a different frame BAR is selected, any\n\
1623frames redirecting their focus to FOO are shifted to redirect their\n\
1624focus to BAR. This allows focus redirection to work properly when the\n\
1625user switches from one frame to another using `select-window'.\n\
1626\n\
1627This means that a frame whose focus is redirected to itself is treated\n\
1628differently from a frame whose focus is redirected to nil; the former\n\
1629is affected by select-frame, while the latter is not.\n\
1630\n\
1631The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1632 (frame, focus_frame)
1633 Lisp_Object frame, focus_frame;
d5e7c279 1634{
13144095
JB
1635 /* Note that we don't check for a live frame here. It's reasonable
1636 to redirect the focus of a frame you're about to delete, if you
1637 know what other frame should receive those keystrokes. */
1638 CHECK_FRAME (frame, 0);
f9898cc6 1639
a42e9724 1640 if (! NILP (focus_frame))
ff11dfa1 1641 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1642
ff11dfa1 1643 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1644
ff11dfa1 1645 if (frame_rehighlight_hook)
dc0700f6 1646 (*frame_rehighlight_hook) (XFRAME (frame));
d5e7c279
JB
1647
1648 return Qnil;
1649}
1650
1651
ff11dfa1
JB
1652DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1653 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1654This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1655See `redirect-frame-focus'.")
1656 (frame)
1657 Lisp_Object frame;
d5e7c279 1658{
ff11dfa1 1659 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1660
ff11dfa1 1661 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1662}
1663
1664
dc6f92b8 1665\f
329ca574
RS
1666/* Return the value of frame parameter PROP in frame FRAME. */
1667
dc6f92b8 1668Lisp_Object
ff11dfa1
JB
1669get_frame_param (frame, prop)
1670 register struct frame *frame;
dc6f92b8
JB
1671 Lisp_Object prop;
1672{
1673 register Lisp_Object tem;
1674
ff11dfa1 1675 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1676 if (EQ (tem, Qnil))
1677 return tem;
1678 return Fcdr (tem);
1679}
1680
329ca574
RS
1681/* Return the buffer-predicate of the selected frame. */
1682
1683Lisp_Object
1684frame_buffer_predicate ()
1685{
1686 return selected_frame->buffer_predicate;
1687}
1688
fa54c6ae
RS
1689/* Return the buffer-list of the selected frame. */
1690
1691Lisp_Object
1692frame_buffer_list ()
1693{
1694 return selected_frame->buffer_list;
1695}
1696
1697/* Set the buffer-list of the selected frame. */
1698
1699void
1700set_frame_buffer_list (list)
1701 Lisp_Object list;
1702{
1703 selected_frame->buffer_list = list;
1704}
1705
1706/* Discard BUFFER from the buffer-list of each frame. */
1707
1708void
1709frames_discard_buffer (buffer)
1710 Lisp_Object buffer;
1711{
1712 Lisp_Object frame, tail;
1713
1714 FOR_EACH_FRAME (tail, frame)
1715 {
1716 XFRAME (frame)->buffer_list
1717 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1718 }
1719}
1720
214b3216
RS
1721/* Move BUFFER to the end of the buffer-list of each frame. */
1722
1723void
1724frames_bury_buffer (buffer)
1725 Lisp_Object buffer;
1726{
1727 Lisp_Object frame, tail;
1728
1729 FOR_EACH_FRAME (tail, frame)
1730 {
1731 XFRAME (frame)->buffer_list
1732 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1733 Fcons (buffer, Qnil));
1734 }
1735}
1736
329ca574
RS
1737/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1738 If the alist already has an element for PROP, we change it. */
1739
dc6f92b8 1740void
fd0c2bd1 1741store_in_alist (alistptr, prop, val)
dc6f92b8 1742 Lisp_Object *alistptr, val;
fd0c2bd1 1743 Lisp_Object prop;
dc6f92b8
JB
1744{
1745 register Lisp_Object tem;
dc6f92b8 1746
dc6f92b8
JB
1747 tem = Fassq (prop, *alistptr);
1748 if (EQ (tem, Qnil))
1749 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1750 else
1751 Fsetcdr (tem, val);
1752}
1753
1754void
ff11dfa1
JB
1755store_frame_param (f, prop, val)
1756 struct frame *f;
dc6f92b8
JB
1757 Lisp_Object prop, val;
1758{
1759 register Lisp_Object tem;
1760
fa54c6ae
RS
1761 if (EQ (prop, Qbuffer_list))
1762 {
1763 f->buffer_list = val;
1764 return;
1765 }
1766
ff11dfa1 1767 tem = Fassq (prop, f->param_alist);
dc6f92b8 1768 if (EQ (tem, Qnil))
ff11dfa1 1769 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1770 else
1771 Fsetcdr (tem, val);
bc93c097 1772
329ca574
RS
1773 if (EQ (prop, Qbuffer_predicate))
1774 f->buffer_predicate = val;
1775
032d78fe 1776 if (! FRAME_WINDOW_P (f))
7e63ac6a
RS
1777 if (EQ (prop, Qmenu_bar_lines))
1778 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
a249de79 1779
e35d291d 1780 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1781 {
1782 if (! MINI_WINDOW_P (XWINDOW (val)))
1783 error ("Surrogate minibuffer windows must be minibuffer windows.");
1784
7af7ef38
KH
1785 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1786 && !EQ (val, f->minibuffer_window))
1787 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1788
1789 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1790 f->minibuffer_window = val;
bc93c097 1791 }
dc6f92b8
JB
1792}
1793
ff11dfa1
JB
1794DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1795 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1796It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1797The meaningful PARMs depend on the kind of frame.\n\
1798If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1799 (frame)
1800 Lisp_Object frame;
dc6f92b8
JB
1801{
1802 Lisp_Object alist;
f769f1b2 1803 FRAME_PTR f;
dd10ec4f 1804 int height, width;
dc6f92b8 1805
ff11dfa1
JB
1806 if (EQ (frame, Qnil))
1807 f = selected_frame;
dc6f92b8
JB
1808 else
1809 {
ff11dfa1
JB
1810 CHECK_FRAME (frame, 0);
1811 f = XFRAME (frame);
dc6f92b8
JB
1812 }
1813
f769f1b2 1814 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1815 return Qnil;
1816
ff11dfa1 1817 alist = Fcopy_alist (f->param_alist);
bb221971
RS
1818#ifdef MSDOS
1819 if (FRAME_MSDOS_P (f))
1820 {
1821 static char *colornames[16] =
1822 {
1823 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1824 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1825 "lightred", "lightmagenta", "yellow", "white"
1826 };
1827 store_in_alist (&alist, intern ("foreground-color"),
1828 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1829 store_in_alist (&alist, intern ("background-color"),
1830 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1831 }
1832 store_in_alist (&alist, intern ("font"), build_string ("default"));
1833#endif
fd0c2bd1 1834 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
1835 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1836 store_in_alist (&alist, Qheight, make_number (height));
1837 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1838 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 1839 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1840 store_in_alist (&alist, Qminibuffer,
39acc701 1841 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1842 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1843 : FRAME_MINIBUF_WINDOW (f)));
1844 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fa54c6ae 1845 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
fd0c2bd1 1846
dbc4e1c1 1847 /* I think this should be done with a hook. */
032d78fe
GV
1848#ifdef HAVE_WINDOW_SYSTEM
1849 if (FRAME_WINDOW_P (f))
ff11dfa1 1850 x_report_frame_params (f, &alist);
b6dd20ed 1851 else
fd0c2bd1 1852#endif
16a3738c
KH
1853 {
1854 /* This ought to be correct in f->param_alist for an X frame. */
1855 Lisp_Object lines;
f4e93c40 1856 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1857 store_in_alist (&alist, Qmenu_bar_lines, lines);
1858 }
dc6f92b8
JB
1859 return alist;
1860}
1861
ff11dfa1
JB
1862DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1863 Smodify_frame_parameters, 2, 2, 0,
1864 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1865ALIST is an alist of parameters to change and their new values.\n\
1866Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
e80f3932
RS
1867The meaningful PARMs depend on the kind of frame.\n\
1868Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1869so that `frame-parameters' will return them.")
ff11dfa1
JB
1870 (frame, alist)
1871 Lisp_Object frame, alist;
dc6f92b8 1872{
fd0c2bd1 1873 FRAME_PTR f;
dc6f92b8
JB
1874 register Lisp_Object tail, elt, prop, val;
1875
ff11dfa1
JB
1876 if (EQ (frame, Qnil))
1877 f = selected_frame;
dc6f92b8
JB
1878 else
1879 {
ff11dfa1
JB
1880 CHECK_LIVE_FRAME (frame, 0);
1881 f = XFRAME (frame);
dc6f92b8
JB
1882 }
1883
dbc4e1c1 1884 /* I think this should be done with a hook. */
032d78fe
GV
1885#ifdef HAVE_WINDOW_SYSTEM
1886 if (FRAME_WINDOW_P (f))
fd0c2bd1 1887 x_set_frame_parameters (f, alist);
329ca574 1888 else
bb221971
RS
1889#endif
1890#ifdef MSDOS
1891 if (FRAME_MSDOS_P (f))
1892 IT_set_frame_parameters (f, alist);
1893 else
329ca574 1894#endif
41d44f1f
RS
1895 {
1896 int length = XINT (Flength (alist));
1897 int i;
1898 Lisp_Object *parms
1899 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1900 Lisp_Object *values
1901 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1902
1903 /* Extract parm names and values into those vectors. */
1904
1905 i = 0;
1906 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1907 {
1908 Lisp_Object elt, prop, val;
1909
1910 elt = Fcar (tail);
1911 parms[i] = Fcar (elt);
1912 values[i] = Fcdr (elt);
1913 i++;
1914 }
1915
1916 /* Now process them in reverse of specified order. */
1917 for (i--; i >= 0; i--)
1918 {
1919 prop = parms[i];
1920 val = values[i];
1921 store_frame_param (f, prop, val);
1922 }
1923 }
dc6f92b8
JB
1924
1925 return Qnil;
1926}
1927\f
a26a1f95
RS
1928DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1929 0, 1, 0,
1930 "Height in pixels of a line in the font in frame FRAME.\n\
1931If FRAME is omitted, the selected frame is used.\n\
1932For a terminal frame, the value is always 1.")
ff11dfa1
JB
1933 (frame)
1934 Lisp_Object frame;
dc6f92b8 1935{
a26a1f95 1936 struct frame *f;
dc6f92b8 1937
a26a1f95
RS
1938 if (NILP (frame))
1939 f = selected_frame;
1940 else
1941 {
1942 CHECK_FRAME (frame, 0);
1943 f = XFRAME (frame);
1944 }
1945
032d78fe
GV
1946#ifdef HAVE_WINDOW_SYSTEM
1947 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1948 return make_number (x_char_height (f));
1949 else
dc6d9681 1950#endif
a26a1f95
RS
1951 return make_number (1);
1952}
dc6d9681 1953
dc6f92b8 1954
a26a1f95
RS
1955DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1956 0, 1, 0,
1957 "Width in pixels of characters in the font in frame FRAME.\n\
1958If FRAME is omitted, the selected frame is used.\n\
1959The width is the same for all characters, because\n\
1960currently Emacs supports only fixed-width fonts.\n\
1961For a terminal screen, the value is always 1.")
1962 (frame)
1963 Lisp_Object frame;
dc6f92b8 1964{
a26a1f95
RS
1965 struct frame *f;
1966
1967 if (NILP (frame))
1968 f = selected_frame;
1969 else
1970 {
1971 CHECK_FRAME (frame, 0);
1972 f = XFRAME (frame);
1973 }
1974
032d78fe
GV
1975#ifdef HAVE_WINDOW_SYSTEM
1976 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1977 return make_number (x_char_width (f));
1978 else
1979#endif
1980 return make_number (1);
dc6f92b8
JB
1981}
1982
a26a1f95
RS
1983DEFUN ("frame-pixel-height", Fframe_pixel_height,
1984 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1985 "Return a FRAME's height in pixels.\n\
1986For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1987If FRAME is omitted, the selected frame is used.")
1988 (frame)
1989 Lisp_Object frame;
dc6f92b8 1990{
a26a1f95
RS
1991 struct frame *f;
1992
1993 if (NILP (frame))
1994 f = selected_frame;
1995 else
1996 {
1997 CHECK_FRAME (frame, 0);
1998 f = XFRAME (frame);
1999 }
2000
032d78fe
GV
2001#ifdef HAVE_WINDOW_SYSTEM
2002 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2003 return make_number (x_pixel_height (f));
2004 else
dc6d9681 2005#endif
a26a1f95
RS
2006 return make_number (FRAME_HEIGHT (f));
2007}
2008
2009DEFUN ("frame-pixel-width", Fframe_pixel_width,
2010 Sframe_pixel_width, 0, 1, 0,
2011 "Return FRAME's width in pixels.\n\
164a14ef 2012For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
2013If FRAME is omitted, the selected frame is used.")
2014 (frame)
2015 Lisp_Object frame;
2016{
2017 struct frame *f;
2018
2019 if (NILP (frame))
2020 f = selected_frame;
2021 else
2022 {
2023 CHECK_FRAME (frame, 0);
2024 f = XFRAME (frame);
2025 }
dc6f92b8 2026
032d78fe
GV
2027#ifdef HAVE_WINDOW_SYSTEM
2028 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2029 return make_number (x_pixel_width (f));
2030 else
2031#endif
2032 return make_number (FRAME_WIDTH (f));
2033}
2034\f
ff11dfa1
JB
2035DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2036 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 2037Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1 2038but that the idea of the actual height of the frame should not be changed.")
735eeca3
EN
2039 (frame, lines, pretend)
2040 Lisp_Object frame, lines, pretend;
dc6f92b8 2041{
ff11dfa1 2042 register struct frame *f;
dc6f92b8 2043
735eeca3 2044 CHECK_NUMBER (lines, 0);
ff11dfa1
JB
2045 if (NILP (frame))
2046 f = selected_frame;
dc6f92b8
JB
2047 else
2048 {
ff11dfa1
JB
2049 CHECK_LIVE_FRAME (frame, 0);
2050 f = XFRAME (frame);
dc6f92b8
JB
2051 }
2052
dbc4e1c1 2053 /* I think this should be done with a hook. */
032d78fe
GV
2054#ifdef HAVE_WINDOW_SYSTEM
2055 if (FRAME_WINDOW_P (f))
dc6f92b8 2056 {
735eeca3
EN
2057 if (XINT (lines) != f->height)
2058 x_set_window_size (f, 1, f->width, XINT (lines));
dc6f92b8
JB
2059 }
2060 else
fd0c2bd1 2061#endif
735eeca3 2062 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
dc6f92b8
JB
2063 return Qnil;
2064}
2065
ff11dfa1
JB
2066DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2067 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 2068Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
2069but that the idea of the actual width of the frame should not be changed.")
2070 (frame, cols, pretend)
fd0c2bd1 2071 Lisp_Object frame, cols, pretend;
dc6f92b8 2072{
ff11dfa1 2073 register struct frame *f;
dc6f92b8 2074 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
2075 if (NILP (frame))
2076 f = selected_frame;
dc6f92b8
JB
2077 else
2078 {
ff11dfa1
JB
2079 CHECK_LIVE_FRAME (frame, 0);
2080 f = XFRAME (frame);
dc6f92b8
JB
2081 }
2082
dbc4e1c1 2083 /* I think this should be done with a hook. */
032d78fe
GV
2084#ifdef HAVE_WINDOW_SYSTEM
2085 if (FRAME_WINDOW_P (f))
dc6f92b8 2086 {
ff11dfa1 2087 if (XINT (cols) != f->width)
808c0f20 2088 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
2089 }
2090 else
fd0c2bd1
JB
2091#endif
2092 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
2093 return Qnil;
2094}
2095
ff11dfa1
JB
2096DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2097 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2098 (frame, cols, rows)
2099 Lisp_Object frame, cols, rows;
dc6f92b8 2100{
ff11dfa1 2101 register struct frame *f;
dc6f92b8
JB
2102 int mask;
2103
ff11dfa1 2104 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2105 CHECK_NUMBER (cols, 2);
2106 CHECK_NUMBER (rows, 1);
ff11dfa1 2107 f = XFRAME (frame);
dc6f92b8 2108
dbc4e1c1 2109 /* I think this should be done with a hook. */
032d78fe
GV
2110#ifdef HAVE_WINDOW_SYSTEM
2111 if (FRAME_WINDOW_P (f))
dc6f92b8 2112 {
29824ce2
RS
2113 if (XINT (rows) != f->height || XINT (cols) != f->width
2114 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2115 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
2116 }
2117 else
fd0c2bd1
JB
2118#endif
2119 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
2120
2121 return Qnil;
2122}
2123
ff11dfa1
JB
2124DEFUN ("set-frame-position", Fset_frame_position,
2125 Sset_frame_position, 3, 3, 0,
2126 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
2127This is actually the position of the upper left corner of the frame.\n\
2128Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 2129the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
2130 (frame, xoffset, yoffset)
2131 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2132{
ff11dfa1 2133 register struct frame *f;
dc6f92b8
JB
2134 int mask;
2135
ff11dfa1 2136 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2137 CHECK_NUMBER (xoffset, 1);
2138 CHECK_NUMBER (yoffset, 2);
ff11dfa1 2139 f = XFRAME (frame);
dc6f92b8 2140
dbc4e1c1 2141 /* I think this should be done with a hook. */
032d78fe
GV
2142#ifdef HAVE_WINDOW_SYSTEM
2143 if (FRAME_WINDOW_P (f))
c7c70761 2144 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2145#endif
dc6f92b8
JB
2146
2147 return Qt;
2148}
dc6d9681 2149
dc6f92b8 2150\f
ff11dfa1 2151syms_of_frame ()
dc6f92b8 2152{
a249de79 2153 syms_of_frame_1 ();
dc6f92b8 2154
ff11dfa1 2155 staticpro (&Vframe_list);
dc6f92b8 2156
ff11dfa1
JB
2157 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2158 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
2159
2160 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 2161 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
2162 Vemacs_iconified = Qnil;
2163
c60f3a6a 2164 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
ff11dfa1 2165 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 2166\n\
ff11dfa1 2167Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
2168appropriate surrogate.\n\
2169\n\
2170Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 2171frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
2172minibuffer, no matter what this variable is set to. This means that\n\
2173this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 2174current set of frames, or where the minibuffer is currently being\n\
f9898cc6 2175displayed.");
dc6f92b8 2176
5add3885 2177 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2178 defsubr (&Sframep);
dbc4e1c1 2179 defsubr (&Sframe_live_p);
bb1513c9 2180 defsubr (&Smake_terminal_frame);
0f85737c 2181 defsubr (&Shandle_switch_frame);
1c212787 2182 defsubr (&Signore_event);
ff11dfa1
JB
2183 defsubr (&Sselect_frame);
2184 defsubr (&Sselected_frame);
2185 defsubr (&Swindow_frame);
2186 defsubr (&Sframe_root_window);
d446a856 2187 defsubr (&Sframe_first_window);
ff11dfa1 2188 defsubr (&Sframe_selected_window);
4a7cfafc 2189 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2190 defsubr (&Sframe_list);
2191 defsubr (&Snext_frame);
ef2c57ac 2192 defsubr (&Sprevious_frame);
ff11dfa1 2193 defsubr (&Sdelete_frame);
f9898cc6 2194 defsubr (&Smouse_position);
152e6c70 2195 defsubr (&Smouse_pixel_position);
dc6f92b8 2196 defsubr (&Sset_mouse_position);
152e6c70 2197 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2198#if 0
ff11dfa1
JB
2199 defsubr (&Sframe_configuration);
2200 defsubr (&Srestore_frame_configuration);
dc6f92b8 2201#endif
ff11dfa1
JB
2202 defsubr (&Smake_frame_visible);
2203 defsubr (&Smake_frame_invisible);
2204 defsubr (&Siconify_frame);
2205 defsubr (&Sframe_visible_p);
2206 defsubr (&Svisible_frame_list);
b49f5578
JB
2207 defsubr (&Sraise_frame);
2208 defsubr (&Slower_frame);
ff11dfa1
JB
2209 defsubr (&Sredirect_frame_focus);
2210 defsubr (&Sframe_focus);
2211 defsubr (&Sframe_parameters);
2212 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2213 defsubr (&Sframe_char_height);
2214 defsubr (&Sframe_char_width);
2215 defsubr (&Sframe_pixel_height);
2216 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2217 defsubr (&Sset_frame_height);
2218 defsubr (&Sset_frame_width);
2219 defsubr (&Sset_frame_size);
2220 defsubr (&Sset_frame_position);
dc6f92b8 2221}
e5d77022 2222
2f0b07e0
JB
2223keys_of_frame ()
2224{
0f85737c 2225 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 2226 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1c212787
KH
2227 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2228 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2f0b07e0 2229}