(paren-blinking group): Doc fix.
[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++;
0303e8da
RS
505 sprintf (name, "F%d", terminal_frame_count);
506 f->name = build_string (name);
bb1513c9 507
bb1513c9
RS
508 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
509 f->async_visible = 1; /* Don't let visible be cleared later. */
bb221971
RS
510#ifdef MSDOS
511 f->output_data.x = &the_only_x_display;
512 f->output_method = output_msdos_raw;
513 init_frame_faces (f);
514#else /* not MSDOS */
7556890b 515 f->output_data.nothing = 1; /* Nonzero means frame isn't deleted. */
bb221971 516#endif
ff11dfa1 517 return f;
dc6f92b8 518}
bb1513c9
RS
519
520DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
4bc7e3ad
RS
521 1, 1, 0, "Create an additional terminal frame.\n\
522You can create multiple frames on a text-only terminal in this way.\n\
523Only the selected terminal frame is actually displayed.\n\
524This function takes one argument, an alist specifying frame parameters.\n\
525In practice, generally you don't need to specify any parameters.\n\
526Note that changing the size of one terminal frame automatically affects all.")
bb1513c9
RS
527 (parms)
528 Lisp_Object parms;
529{
530 struct frame *f;
531 Lisp_Object frame;
532
541580aa 533#ifdef MSDOS
bb221971
RS
534 if (selected_frame->output_method != output_msdos_raw)
535 abort ();
536#else
bb1513c9
RS
537 if (selected_frame->output_method != output_termcap)
538 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
bb221971 539#endif
bb1513c9
RS
540
541 f = make_terminal_frame ();
542 change_frame_size (f, FRAME_HEIGHT (selected_frame),
543 FRAME_WIDTH (selected_frame), 0, 0);
544 remake_frame_glyphs (f);
545 calculate_costs (f);
546 XSETFRAME (frame, f);
8adfc1ec 547 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
bb1513c9 548 Fmodify_frame_parameters (frame, parms);
133c7a8a 549 f->face_alist = selected_frame->face_alist;
bb1513c9
RS
550 return frame;
551}
dc6f92b8 552\f
61f94483 553Lisp_Object
0aed85f4 554do_switch_frame (frame, no_enter, track)
ff11dfa1 555 Lisp_Object frame, no_enter;
0aed85f4 556 int track;
dc6f92b8 557{
2f0b07e0
JB
558 /* If FRAME is a switch-frame event, extract the frame we should
559 switch to. */
560 if (CONSP (frame)
561 && EQ (XCONS (frame)->car, Qswitch_frame)
562 && CONSP (XCONS (frame)->cdr))
563 frame = XCONS (XCONS (frame)->cdr)->car;
564
09907c3a
KH
565 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
566 a switch-frame event to arrive after a frame is no longer live,
567 especially when deleting the initial frame during startup. */
568 CHECK_FRAME (frame, 0);
569 if (! FRAME_LIVE_P (XFRAME (frame)))
570 return Qnil;
dc6f92b8 571
ff11dfa1
JB
572 if (selected_frame == XFRAME (frame))
573 return frame;
dc6f92b8 574
0aed85f4
KH
575 /* This is too greedy; it causes inappropriate focus redirection
576 that's hard to get rid of. */
577#if 0
a42e9724
JB
578 /* If a frame's focus has been redirected toward the currently
579 selected frame, we should change the redirection to point to the
580 newly selected frame. This means that if the focus is redirected
581 from a minibufferless frame to a surrogate minibuffer frame, we
582 can use `other-window' to switch between all the frames using
583 that minibuffer frame, and the focus redirection will follow us
584 around. */
0aed85f4
KH
585 if (track)
586 {
587 Lisp_Object tail;
a42e9724 588
0aed85f4
KH
589 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
590 {
591 Lisp_Object focus;
a42e9724 592
e35d291d 593 if (!FRAMEP (XCONS (tail)->car))
0aed85f4 594 abort ();
a42e9724 595
0aed85f4 596 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
a42e9724 597
e35d291d 598 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
0aed85f4
KH
599 Fredirect_frame_focus (XCONS (tail)->car, frame);
600 }
601 }
602#else /* ! 0 */
603 /* Instead, apply it only to the frame we're pointing to. */
032d78fe
GV
604#ifdef HAVE_WINDOW_SYSTEM
605 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
0aed85f4
KH
606 {
607 Lisp_Object focus, xfocus;
608
d7266360 609 xfocus = x_get_focus_frame (XFRAME (frame));
0aed85f4
KH
610 if (FRAMEP (xfocus))
611 {
612 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
613 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
614 Fredirect_frame_focus (xfocus, frame);
615 }
616 }
617#endif /* HAVE_X_WINDOWS */
618#endif /* ! 0 */
a42e9724 619
ff11dfa1
JB
620 selected_frame = XFRAME (frame);
621 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
622 last_nonminibuf_frame = selected_frame;
d5e7c279 623
ff11dfa1 624 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8 625
074577b8 626 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 627 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
628 before you take it out, make sure that evaluating something like
629 (select-window (frame-root-window (new-frame))) doesn't end up
630 with your typing being interpreted in the new frame instead of
631 the one you're actually typing in. */
ef352596 632 internal_last_event_frame = Qnil;
074577b8 633
ff11dfa1 634 return frame;
dc6f92b8
JB
635}
636
0aed85f4
KH
637DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
638 "Select the frame FRAME.\n\
639Subsequent editing commands apply to its selected window.\n\
640The selection of FRAME lasts until the next time the user does\n\
641something to select a different frame, or until the next time this\n\
642function is called.")
643 (frame, no_enter)
644 Lisp_Object frame, no_enter;
645{
646 return do_switch_frame (frame, no_enter, 1);
647}
648
649
650DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
651 "Handle a switch-frame event EVENT.\n\
652Switch-frame events are usually bound to this function.\n\
653A switch-frame event tells Emacs that the window manager has requested\n\
654that the user's events be directed to the frame mentioned in the event.\n\
655This function selects the selected window of the frame of EVENT.\n\
656\n\
657If EVENT is frame object, handle it as if it were a switch-frame event\n\
658to that frame.")
735eeca3
EN
659 (event, no_enter)
660 Lisp_Object event, no_enter;
0aed85f4 661{
6951cd71
KH
662 /* Preserve prefix arg that the command loop just cleared. */
663 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
e05169e2 664 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
735eeca3 665 return do_switch_frame (event, no_enter, 0);
0aed85f4
KH
666}
667
1c212787
KH
668DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
669 "Do nothing, but preserve any prefix argument already specified.\n\
670This is a suitable binding for iconify-frame and make-frame-visible.")
671 ()
672{
673 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
674 return Qnil;
675}
0aed85f4 676
ff11dfa1
JB
677DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
678 "Return the frame that is now selected.")
dc6f92b8
JB
679 ()
680{
681 Lisp_Object tem;
2d80a27a 682 XSETFRAME (tem, selected_frame);
dc6f92b8
JB
683 return tem;
684}
4a7cfafc 685\f
ff11dfa1
JB
686DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
687 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
688 (window)
689 Lisp_Object window;
690{
774910eb 691 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 692 return XWINDOW (window)->frame;
dc6f92b8
JB
693}
694
ba32f2db
KH
695DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
696 "Returns the topmost, leftmost window of FRAME.\n\
697If omitted, FRAME defaults to the currently selected frame.")
698 (frame)
699 Lisp_Object frame;
700{
701 Lisp_Object w;
702
703 if (NILP (frame))
704 w = selected_frame->root_window;
705 else
706 {
707 CHECK_LIVE_FRAME (frame, 0);
708 w = XFRAME (frame)->root_window;
709 }
710 while (NILP (XWINDOW (w)->buffer))
711 {
712 if (! NILP (XWINDOW (w)->hchild))
713 w = XWINDOW (w)->hchild;
714 else if (! NILP (XWINDOW (w)->vchild))
715 w = XWINDOW (w)->vchild;
716 else
717 abort ();
718 }
719 return w;
720}
721
5add3885
RS
722DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
723 Sactive_minibuffer_window, 0, 0, 0,
724 "Return the currently active minibuffer window, or nil if none.")
725 ()
726{
727 return minibuf_level ? minibuf_window : Qnil;
728}
729
ff11dfa1 730DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
731 "Returns the root-window of FRAME.\n\
732If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
733 (frame)
734 Lisp_Object frame;
dc6f92b8 735{
ff11dfa1 736 if (NILP (frame))
2d80a27a 737 XSETFRAME (frame, selected_frame);
f9898cc6 738 else
ff11dfa1 739 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 740
ff11dfa1 741 return XFRAME (frame)->root_window;
dc6f92b8
JB
742}
743
ff11dfa1
JB
744DEFUN ("frame-selected-window", Fframe_selected_window,
745 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
746 "Return the selected window of frame object FRAME.\n\
747If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
748 (frame)
749 Lisp_Object frame;
dc6f92b8 750{
ff11dfa1 751 if (NILP (frame))
2d80a27a 752 XSETFRAME (frame, selected_frame);
f9898cc6 753 else
ff11dfa1 754 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 755
ff11dfa1 756 return XFRAME (frame)->selected_window;
dc6f92b8
JB
757}
758
4a7cfafc
RS
759DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
760 Sset_frame_selected_window, 2, 2, 0,
761 "Set the selected window of frame object FRAME to WINDOW.\n\
762If FRAME is nil, the selected frame is used.\n\
763If FRAME is the selected frame, this makes WINDOW the selected window.")
764 (frame, window)
765 Lisp_Object frame, window;
766{
767 if (NILP (frame))
2d80a27a 768 XSETFRAME (frame, selected_frame);
4a7cfafc
RS
769 else
770 CHECK_LIVE_FRAME (frame, 0);
771
772 CHECK_LIVE_WINDOW (window, 1);
773
774 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
775 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
776
777 if (XFRAME (frame) == selected_frame)
778 return Fselect_window (window);
779
780 return XFRAME (frame)->selected_window = window;
781}
782\f
ff11dfa1 783DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 784 0, 0, 0,
ff11dfa1 785 "Return a list of all frames.")
dc6f92b8
JB
786 ()
787{
ff11dfa1 788 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
789}
790
ff11dfa1 791/* Return the next frame in the frame list after FRAME.
ff11dfa1 792 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
793 If MINIBUF is a window, include only its own frame
794 and any frame now using that window as the minibuffer.
f7af3f7b 795 If MINIBUF is `visible', include all visible frames.
a9986780 796 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
797 Otherwise, include all frames. */
798
dc6f92b8 799Lisp_Object
ff11dfa1
JB
800next_frame (frame, minibuf)
801 Lisp_Object frame;
f9898cc6 802 Lisp_Object minibuf;
dc6f92b8
JB
803{
804 Lisp_Object tail;
805 int passed = 0;
806
ff11dfa1
JB
807 /* There must always be at least one frame in Vframe_list. */
808 if (! CONSP (Vframe_list))
f9898cc6
JB
809 abort ();
810
dbc4e1c1
JB
811 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
812 forever. Forestall that. */
813 CHECK_LIVE_FRAME (frame, 0);
814
dc6f92b8 815 while (1)
ff11dfa1 816 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 817 {
ab9f008d 818 Lisp_Object f;
d06a8a56 819
ab9f008d 820 f = XCONS (tail)->car;
06537cc8
RS
821
822 if (passed
823 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
d5e7c279 824 {
d06a8a56
JB
825 /* Decide whether this frame is eligible to be returned. */
826
827 /* If we've looped all the way around without finding any
828 eligible frames, return the original frame. */
829 if (EQ (f, frame))
830 return f;
831
832 /* Let minibuf decide if this frame is acceptable. */
833 if (NILP (minibuf))
834 {
835 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
836 return f;
837 }
f7af3f7b
RS
838 else if (EQ (minibuf, Qvisible))
839 {
840 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
841 if (FRAME_VISIBLE_P (XFRAME (f)))
842 return f;
843 }
a9986780
RS
844 else if (XFASTINT (minibuf) == 0)
845 {
846 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
847 if (FRAME_VISIBLE_P (XFRAME (f))
848 || FRAME_ICONIFIED_P (XFRAME (f)))
849 return f;
850 }
f7af3f7b 851 else if (WINDOWP (minibuf))
d06a8a56 852 {
a9986780
RS
853 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
854 /* Check that F either is, or has forwarded its focus to,
855 MINIBUF's frame. */
856 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
857 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
858 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
859 return f;
860 }
861 else
ff11dfa1 862 return f;
d5e7c279 863 }
dc6f92b8 864
d06a8a56 865 if (EQ (frame, f))
dc6f92b8
JB
866 passed++;
867 }
868}
869
ff11dfa1 870/* Return the previous frame in the frame list before FRAME.
ff11dfa1 871 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
872 If MINIBUF is a window, include only its own frame
873 and any frame now using that window as the minibuffer.
f7af3f7b 874 If MINIBUF is `visible', include all visible frames.
a9986780 875 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
876 Otherwise, include all frames. */
877
dc6f92b8 878Lisp_Object
ff11dfa1
JB
879prev_frame (frame, minibuf)
880 Lisp_Object frame;
f9898cc6 881 Lisp_Object minibuf;
dc6f92b8
JB
882{
883 Lisp_Object tail;
884 Lisp_Object prev;
885
ff11dfa1
JB
886 /* There must always be at least one frame in Vframe_list. */
887 if (! CONSP (Vframe_list))
f9898cc6
JB
888 abort ();
889
dc6f92b8 890 prev = Qnil;
d06a8a56 891 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 892 {
ab9f008d 893 Lisp_Object f;
f9898cc6 894
ab9f008d 895 f = XCONS (tail)->car;
e35d291d 896 if (!FRAMEP (f))
d06a8a56 897 abort ();
f9898cc6 898
d06a8a56
JB
899 if (EQ (frame, f) && !NILP (prev))
900 return prev;
f9898cc6 901
06537cc8 902 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
f7af3f7b 903 {
06537cc8
RS
904 /* Decide whether this frame is eligible to be returned,
905 according to minibuf. */
906 if (NILP (minibuf))
907 {
908 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
909 prev = f;
910 }
911 else if (WINDOWP (minibuf))
912 {
913 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
914 /* Check that F either is, or has forwarded its focus to,
915 MINIBUF's frame. */
916 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
917 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
918 FRAME_FOCUS_FRAME (XFRAME (f)))))
919 prev = f;
920 }
921 else if (EQ (minibuf, Qvisible))
922 {
923 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
924 if (FRAME_VISIBLE_P (XFRAME (f)))
925 prev = f;
926 }
927 else if (XFASTINT (minibuf) == 0)
928 {
929 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
930 if (FRAME_VISIBLE_P (XFRAME (f))
931 || FRAME_ICONIFIED_P (XFRAME (f)))
932 prev = f;
933 }
934 else
a9986780
RS
935 prev = f;
936 }
f9898cc6 937 }
d06a8a56
JB
938
939 /* We've scanned the entire list. */
940 if (NILP (prev))
941 /* We went through the whole frame list without finding a single
942 acceptable frame. Return the original frame. */
943 return frame;
944 else
945 /* There were no acceptable frames in the list before FRAME; otherwise,
946 we would have returned directly from the loop. Since PREV is the last
947 acceptable frame in the list, return it. */
948 return prev;
dc6f92b8
JB
949}
950
ef2c57ac 951
ff11dfa1
JB
952DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
953 "Return the next frame in the frame list after FRAME.\n\
06537cc8 954It considers only frames on the same terminal as FRAME.\n\
a42e9724 955By default, skip minibuffer-only frames.\n\
d06a8a56 956If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 957If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 958If MINIFRAME is a window, include only its own frame\n\
a9986780 959and any frame now using that window as the minibuffer.\n\
f7af3f7b 960If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 961If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 962Otherwise, include all frames.")
ff11dfa1 963 (frame, miniframe)
8693ca83 964 Lisp_Object frame, miniframe;
dc6f92b8
JB
965{
966 Lisp_Object tail;
967
ff11dfa1 968 if (NILP (frame))
2d80a27a 969 XSETFRAME (frame, selected_frame);
f9898cc6 970 else
ff11dfa1 971 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 972
ff11dfa1 973 return next_frame (frame, miniframe);
dc6f92b8 974}
dbc4e1c1 975
ef2c57ac
RM
976DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
977 "Return the previous frame in the frame list before FRAME.\n\
06537cc8 978It considers only frames on the same terminal as FRAME.\n\
ef2c57ac
RM
979By default, skip minibuffer-only frames.\n\
980If omitted, FRAME defaults to the selected frame.\n\
981If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 982If MINIFRAME is a window, include only its own frame\n\
a9986780 983and any frame now using that window as the minibuffer.\n\
f7af3f7b 984If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 985If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 986Otherwise, include all frames.")
ef2c57ac
RM
987 (frame, miniframe)
988 Lisp_Object frame, miniframe;
989{
990 Lisp_Object tail;
991
992 if (NILP (frame))
2d80a27a 993 XSETFRAME (frame, selected_frame);
ef2c57ac
RM
994 else
995 CHECK_LIVE_FRAME (frame, 0);
996
997 return prev_frame (frame, miniframe);
998}
dc6f92b8 999\f
808c0f20
RS
1000/* Return 1 if it is ok to delete frame F;
1001 0 if all frames aside from F are invisible.
1002 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1003
d56b45eb 1004int
808c0f20
RS
1005other_visible_frames (f)
1006 FRAME_PTR f;
1007{
1008 /* We know the selected frame is visible,
1009 so if F is some other frame, it can't be the sole visible one. */
1010 if (f == selected_frame)
c08c95c7
RS
1011 {
1012 Lisp_Object frames;
1013 int count = 0;
1014
1015 for (frames = Vframe_list;
1016 CONSP (frames);
1017 frames = XCONS (frames)->cdr)
1018 {
ab9f008d 1019 Lisp_Object this;
c08c95c7 1020
ab9f008d 1021 this = XCONS (frames)->car;
808c0f20
RS
1022 /* Verify that the frame's window still exists
1023 and we can still talk to it. And note any recent change
1024 in visibility. */
032d78fe
GV
1025#ifdef HAVE_WINDOW_SYSTEM
1026 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1027 {
b0509a40 1028 x_sync (XFRAME (this));
5e7b7c5b
RS
1029 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1030 }
1031#endif
1032
c08c95c7
RS
1033 if (FRAME_VISIBLE_P (XFRAME (this))
1034 || FRAME_ICONIFIED_P (XFRAME (this))
1035 /* Allow deleting the terminal frame when at least
1036 one X frame exists! */
032d78fe 1037 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1038 count++;
1039 }
808c0f20 1040 return count > 1;
c08c95c7 1041 }
808c0f20
RS
1042 return 1;
1043}
1044
1045DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1046 "Delete FRAME, permanently eliminating it from use.\n\
1047If omitted, FRAME defaults to the selected frame.\n\
1048A frame may not be deleted if its minibuffer is used by other frames.\n\
1049Normally, you may not delete a frame if all other frames are invisible,\n\
1050but if the second optional argument FORCE is non-nil, you may do so.")
1051 (frame, force)
1052 Lisp_Object frame, force;
1053{
1054 struct frame *f;
99b92e64 1055 int minibuffer_selected;
808c0f20
RS
1056
1057 if (EQ (frame, Qnil))
1058 {
1059 f = selected_frame;
2d80a27a 1060 XSETFRAME (frame, f);
808c0f20
RS
1061 }
1062 else
1063 {
1064 CHECK_FRAME (frame, 0);
1065 f = XFRAME (frame);
1066 }
1067
1068 if (! FRAME_LIVE_P (f))
1069 return Qnil;
1070
1071 if (NILP (force) && !other_visible_frames (f))
1072 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1073
ff11dfa1
JB
1074 /* Does this frame have a minibuffer, and is it the surrogate
1075 minibuffer for any other frame? */
fd0c2bd1 1076 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1077 {
ff11dfa1 1078 Lisp_Object frames;
1113d9db 1079
ff11dfa1
JB
1080 for (frames = Vframe_list;
1081 CONSP (frames);
1082 frames = XCONS (frames)->cdr)
1113d9db 1083 {
7a8cc307
RS
1084 Lisp_Object this;
1085 this = XCONS (frames)->car;
1113d9db 1086
ff11dfa1
JB
1087 if (! EQ (this, frame)
1088 && EQ (frame,
7a8cc307
RS
1089 WINDOW_FRAME (XWINDOW
1090 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 1091 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 1092 }
dc6f92b8
JB
1093 }
1094
99b92e64
RS
1095 minibuffer_selected = EQ (minibuf_window, selected_window);
1096
ff11dfa1
JB
1097 /* Don't let the frame remain selected. */
1098 if (f == selected_frame)
06537cc8
RS
1099 {
1100 Lisp_Object tail, frame1;
1101
1102 /* Look for another visible frame on the same terminal. */
1103 frame1 = next_frame (frame, Qvisible);
1104
1105 /* If there is none, find *some* other frame. */
1106 if (NILP (frame1) || EQ (frame1, frame))
1107 {
1108 FOR_EACH_FRAME (tail, frame1)
1109 {
1110 if (! EQ (frame, frame1))
1111 break;
1112 }
1113 }
1114
1115 do_switch_frame (frame1, Qnil, 0);
1116 }
dc6f92b8 1117
ff11dfa1
JB
1118 /* Don't allow minibuf_window to remain on a deleted frame. */
1119 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1120 {
ff11dfa1 1121 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1122 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1123 minibuf_window = selected_frame->minibuffer_window;
99b92e64
RS
1124
1125 /* If the dying minibuffer window was selected,
1126 select the new one. */
1127 if (minibuffer_selected)
1128 Fselect_window (minibuf_window);
dc6f92b8
JB
1129 }
1130
bb2a0a65
RS
1131 /* Clear any X selections for this frame. */
1132#ifdef HAVE_X_WINDOWS
1133 if (FRAME_X_P (f))
1134 x_clear_frame_selections (f);
1135#endif
1136
4a88b3b0
JB
1137 /* Mark all the windows that used to be on FRAME as deleted, and then
1138 remove the reference to them. */
1139 delete_all_subwindows (XWINDOW (f->root_window));
1140 f->root_window = Qnil;
1141
ff11dfa1 1142 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1143 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1144
60a8823e
KH
1145 if (f->namebuf)
1146 free (f->namebuf);
d2bee99e
RS
1147 if (FRAME_CURRENT_GLYPHS (f))
1148 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
1149 if (FRAME_DESIRED_GLYPHS (f))
1150 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
1151 if (FRAME_TEMP_GLYPHS (f))
1152 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
1153 if (FRAME_INSERT_COST (f))
1154 free (FRAME_INSERT_COST (f));
1155 if (FRAME_DELETEN_COST (f))
09d1d7e2 1156 free (FRAME_DELETEN_COST (f));
d2bee99e 1157 if (FRAME_INSERTN_COST (f))
09d1d7e2 1158 free (FRAME_INSERTN_COST (f));
d2bee99e 1159 if (FRAME_DELETE_COST (f))
09d1d7e2 1160 free (FRAME_DELETE_COST (f));
25734faf
RS
1161 if (FRAME_MESSAGE_BUF (f))
1162 free (FRAME_MESSAGE_BUF (f));
d2bee99e 1163
71025e5e
KH
1164#ifdef HAVE_WINDOW_SYSTEM
1165 /* Free all fontset data. */
1166 free_fontset_data (FRAME_FONTSET_DATA (f));
1167#endif
1168
8678b9cc
JB
1169 /* Since some events are handled at the interrupt level, we may get
1170 an event for f at any time; if we zero out the frame's display
1171 now, then we may trip up the event-handling code. Instead, we'll
1172 promise that the display of the frame must be valid until we have
1173 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
1174
1175 /* I think this should be done with a hook. */
032d78fe
GV
1176#ifdef HAVE_WINDOW_SYSTEM
1177 if (FRAME_WINDOW_P (f))
8678b9cc 1178 x_destroy_window (f);
d5e7c279
JB
1179#endif
1180
7556890b 1181 f->output_data.nothing = 0;
8678b9cc 1182
ff11dfa1 1183 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1184 another one. */
ff11dfa1 1185 if (f == last_nonminibuf_frame)
d5e7c279 1186 {
ff11dfa1 1187 Lisp_Object frames;
1113d9db 1188
ff11dfa1 1189 last_nonminibuf_frame = 0;
d5e7c279 1190
ff11dfa1
JB
1191 for (frames = Vframe_list;
1192 CONSP (frames);
1193 frames = XCONS (frames)->cdr)
d5e7c279 1194 {
ff11dfa1
JB
1195 f = XFRAME (XCONS (frames)->car);
1196 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1197 {
ff11dfa1 1198 last_nonminibuf_frame = f;
d5e7c279
JB
1199 break;
1200 }
1201 }
1202 }
dc6f92b8 1203
c4c6d073
KH
1204 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1205 find another one. Prefer minibuffer-only frames, but also notice
1206 frames with other windows. */
c60f3a6a 1207 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1113d9db 1208 {
ff11dfa1 1209 Lisp_Object frames;
1113d9db 1210
ff11dfa1 1211 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1212 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1213 /* Some frame we found on the same kboard, or nil if there are none. */
1214 Lisp_Object frame_on_same_kboard;
1113d9db 1215
32fda9ba 1216 frame_on_same_kboard = Qnil;
ab9f008d 1217 frame_with_minibuf = Qnil;
32fda9ba 1218
ff11dfa1
JB
1219 for (frames = Vframe_list;
1220 CONSP (frames);
1221 frames = XCONS (frames)->cdr)
1113d9db 1222 {
ab9f008d 1223 Lisp_Object this;
c4c6d073 1224 struct frame *f1;
1113d9db 1225
ab9f008d 1226 this = XCONS (frames)->car;
e35d291d 1227 if (!FRAMEP (this))
1113d9db 1228 abort ();
c4c6d073 1229 f1 = XFRAME (this);
1113d9db 1230
c4c6d073
KH
1231 /* Consider only frames on the same kboard
1232 and only those with minibuffers. */
1233 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1234 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1235 {
ff11dfa1 1236 frame_with_minibuf = this;
c4c6d073 1237 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1238 break;
1239 }
32fda9ba
RS
1240
1241 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1242 frame_on_same_kboard = this;
1113d9db
JB
1243 }
1244
32fda9ba
RS
1245 if (!NILP (frame_on_same_kboard))
1246 {
1247 /* We know that there must be some frame with a minibuffer out
1248 there. If this were not true, all of the frames present
1249 would have to be minibufferless, which implies that at some
1250 point their minibuffer frames must have been deleted, but
1251 that is prohibited at the top; you can't delete surrogate
1252 minibuffer frames. */
1253 if (NILP (frame_with_minibuf))
1254 abort ();
1113d9db 1255
32fda9ba
RS
1256 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1257 }
1258 else
1259 /* No frames left on this kboard--say no minibuffer either. */
1260 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1261 }
1262
e681c92a
RS
1263 /* Cause frame titles to update--necessary if we now have just one frame. */
1264 update_mode_lines = 1;
1265
dc6f92b8
JB
1266 return Qnil;
1267}
1268\f
1269/* Return mouse position in character cell units. */
1270
f9898cc6 1271DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1272 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1273The position is given in character cells, where (0, 0) is the\n\
1274upper-left corner.\n\
f9898cc6 1275If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1276to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1277and nil for X and Y.")
1278 ()
dc6f92b8 1279{
ff11dfa1 1280 FRAME_PTR f;
dbc4e1c1 1281 Lisp_Object lispy_dummy;
fd2777e0 1282 enum scroll_bar_part party_dummy;
dbc4e1c1 1283 Lisp_Object x, y;
5384466a 1284 int col, row;
dbc4e1c1 1285 unsigned long long_dummy;
dc6f92b8 1286
c5074d8c
RS
1287 f = selected_frame;
1288 x = y = Qnil;
1289
f443c170 1290#ifdef HAVE_MOUSE
c5074d8c 1291 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1292 if (mouse_position_hook)
0c5c1cf7 1293 (*mouse_position_hook) (&f, 0,
dbc4e1c1
JB
1294 &lispy_dummy, &party_dummy,
1295 &x, &y,
1296 &long_dummy);
76db7eb4
KH
1297 if (! NILP (x))
1298 {
1299 col = XINT (x);
1300 row = XINT (y);
8126c3b4 1301 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1302 XSETINT (x, col);
1303 XSETINT (y, row);
1304 }
f443c170 1305#endif
2d80a27a 1306 XSETFRAME (lispy_dummy, f);
c5074d8c 1307 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1308}
1309
152e6c70
RS
1310DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1311 Smouse_pixel_position, 0, 0, 0,
1312 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1313The position is given in pixel units, where (0, 0) is the\n\
1314upper-left corner.\n\
1315If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1316to read the mouse position, it returns the selected frame for FRAME\n\
1317and nil for X and Y.")
1318 ()
1319{
1320 FRAME_PTR f;
1321 Lisp_Object lispy_dummy;
1322 enum scroll_bar_part party_dummy;
1323 Lisp_Object x, y;
1324 int col, row;
1325 unsigned long long_dummy;
1326
1327 f = selected_frame;
1328 x = y = Qnil;
1329
0c5c1cf7 1330#ifdef HAVE_MOUSE
152e6c70
RS
1331 /* It's okay for the hook to refrain from storing anything. */
1332 if (mouse_position_hook)
0c5c1cf7 1333 (*mouse_position_hook) (&f, 0,
152e6c70
RS
1334 &lispy_dummy, &party_dummy,
1335 &x, &y,
1336 &long_dummy);
0c5c1cf7 1337#endif
2d80a27a 1338 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1339 return Fcons (lispy_dummy, Fcons (x, y));
1340}
1341
dc6f92b8 1342DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1343 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
efb57f43
RS
1344Note, this is a no-op for an X frame that is not visible.\n\
1345If you have just created a frame, you must wait for it to become visible\n\
1346before calling this function on it, like this.\n\
1347 (while (not (frame-visible-p frame)) (sleep-for .5))")
ff11dfa1
JB
1348 (frame, x, y)
1349 Lisp_Object frame, x, y;
dc6f92b8 1350{
ff11dfa1 1351 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1352 CHECK_NUMBER (x, 2);
1353 CHECK_NUMBER (y, 1);
1354
dbc4e1c1 1355 /* I think this should be done with a hook. */
032d78fe
GV
1356#ifdef HAVE_WINDOW_SYSTEM
1357 if (FRAME_WINDOW_P (XFRAME (frame)))
dc6f92b8 1358 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1359 x_set_mouse_position (XFRAME (frame), x, y);
bb221971 1360#else
be625e00 1361#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1362 if (FRAME_MSDOS_P (XFRAME (frame)))
1363 {
1364 Fselect_frame (frame, Qnil);
1365 mouse_moveto (XINT (x), XINT (y));
1366 }
1367#endif
dc6f92b8
JB
1368#endif
1369
1370 return Qnil;
1371}
152e6c70
RS
1372
1373DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1374 Sset_mouse_pixel_position, 3, 3, 0,
1375 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
efb57f43
RS
1376Note, this is a no-op for an X frame that is not visible.\n\
1377If you have just created a frame, you must wait for it to become visible\n\
1378before calling this function on it, like this.\n\
1379 (while (not (frame-visible-p frame)) (sleep-for .5))")
152e6c70
RS
1380 (frame, x, y)
1381 Lisp_Object frame, x, y;
1382{
1383 CHECK_LIVE_FRAME (frame, 0);
1384 CHECK_NUMBER (x, 2);
1385 CHECK_NUMBER (y, 1);
1386
1387 /* I think this should be done with a hook. */
032d78fe
GV
1388#ifdef HAVE_WINDOW_SYSTEM
1389 if (FRAME_WINDOW_P (XFRAME (frame)))
152e6c70
RS
1390 /* Warping the mouse will cause enternotify and focus events. */
1391 x_set_mouse_pixel_position (XFRAME (frame), x, y);
bb221971 1392#else
be625e00 1393#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1394 if (FRAME_MSDOS_P (XFRAME (frame)))
1395 {
1396 Fselect_frame (frame, Qnil);
1397 mouse_moveto (XINT (x), XINT (y));
1398 }
1399#endif
152e6c70
RS
1400#endif
1401
1402 return Qnil;
1403}
dc6f92b8 1404\f
ff11dfa1 1405DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1406 0, 1, "",
ff11dfa1 1407 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1408If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1409 (frame)
1410 Lisp_Object frame;
dc6f92b8 1411{
1aa66088 1412 if (NILP (frame))
2d80a27a 1413 XSETFRAME (frame, selected_frame);
1aa66088 1414
ff11dfa1 1415 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1416
dbc4e1c1 1417 /* I think this should be done with a hook. */
032d78fe
GV
1418#ifdef HAVE_WINDOW_SYSTEM
1419 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1420 {
1421 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1422 x_make_frame_visible (XFRAME (frame));
1423 }
fd0c2bd1 1424#endif
dc6f92b8 1425
565620a5
RS
1426 /* Make menu bar update for the Buffers and Frams menus. */
1427 windows_or_buffers_changed++;
1428
ff11dfa1 1429 return frame;
dc6f92b8
JB
1430}
1431
ff11dfa1 1432DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1433 0, 2, "",
8693ca83 1434 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1435If omitted, FRAME defaults to the currently selected frame.\n\
1436Normally you may not make FRAME invisible if all other frames are invisible,\n\
1437but if the second optional argument FORCE is non-nil, you may do so.")
1438 (frame, force)
1439 Lisp_Object frame, force;
dc6f92b8 1440{
1aa66088 1441 if (NILP (frame))
2d80a27a 1442 XSETFRAME (frame, selected_frame);
1aa66088 1443
ff11dfa1 1444 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1445
808c0f20
RS
1446 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1447 error ("Attempt to make invisible the sole visible or iconified frame");
1448
3d378fdf 1449#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1450 /* Don't let the frame remain selected. */
1451 if (XFRAME (frame) == selected_frame)
61f94483 1452 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
3d378fdf 1453#endif
9c394f17
RS
1454
1455 /* Don't allow minibuf_window to remain on a deleted frame. */
1456 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1457 {
1458 Fset_window_buffer (selected_frame->minibuffer_window,
1459 XWINDOW (minibuf_window)->buffer);
1460 minibuf_window = selected_frame->minibuffer_window;
1461 }
1462
dbc4e1c1 1463 /* I think this should be done with a hook. */
032d78fe
GV
1464#ifdef HAVE_WINDOW_SYSTEM
1465 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1466 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1467#endif
dc6f92b8 1468
565620a5
RS
1469 /* Make menu bar update for the Buffers and Frams menus. */
1470 windows_or_buffers_changed++;
1471
dc6f92b8
JB
1472 return Qnil;
1473}
1474
ff11dfa1 1475DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1476 0, 1, "",
8693ca83
JB
1477 "Make the frame FRAME into an icon.\n\
1478If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1479 (frame)
1480 Lisp_Object frame;
dc6f92b8 1481{
1aa66088 1482 if (NILP (frame))
2d80a27a 1483 XSETFRAME (frame, selected_frame);
1aa66088 1484
ff11dfa1 1485 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1486
3d378fdf 1487#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1488 /* Don't let the frame remain selected. */
1489 if (XFRAME (frame) == selected_frame)
1490 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1491#endif
9c394f17
RS
1492
1493 /* Don't allow minibuf_window to remain on a deleted frame. */
1494 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1495 {
1496 Fset_window_buffer (selected_frame->minibuffer_window,
1497 XWINDOW (minibuf_window)->buffer);
1498 minibuf_window = selected_frame->minibuffer_window;
1499 }
1500
dbc4e1c1 1501 /* I think this should be done with a hook. */
032d78fe
GV
1502#ifdef HAVE_WINDOW_SYSTEM
1503 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1504 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1505#endif
dc6f92b8 1506
565620a5
RS
1507 /* Make menu bar update for the Buffers and Frams menus. */
1508 windows_or_buffers_changed++;
1509
dc6f92b8
JB
1510 return Qnil;
1511}
1512
ff11dfa1 1513DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1514 1, 1, 0,
ff11dfa1
JB
1515 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1516A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1517a window system, it may not show at all.\n\
fd0c2bd1 1518Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1519 (frame)
1520 Lisp_Object frame;
dc6f92b8 1521{
ff11dfa1 1522 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1523
5c044f55
RS
1524 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1525
a42e9724 1526 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1527 return Qt;
a42e9724 1528 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1529 return Qicon;
dc6f92b8
JB
1530 return Qnil;
1531}
1532
ff11dfa1 1533DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1534 0, 0, 0,
ff11dfa1 1535 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1536 ()
1537{
ff11dfa1
JB
1538 Lisp_Object tail, frame;
1539 struct frame *f;
dc6f92b8
JB
1540 Lisp_Object value;
1541
1542 value = Qnil;
ff11dfa1 1543 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1544 {
ff11dfa1 1545 frame = XCONS (tail)->car;
e35d291d 1546 if (!FRAMEP (frame))
dc6f92b8 1547 continue;
ff11dfa1 1548 f = XFRAME (frame);
a42e9724 1549 if (FRAME_VISIBLE_P (f))
ff11dfa1 1550 value = Fcons (frame, value);
dc6f92b8
JB
1551 }
1552 return value;
1553}
d5e7c279
JB
1554
1555
e518d5e1 1556DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
dbc4e1c1
JB
1557 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1558If FRAME is invisible, make it visible.\n\
828ac693 1559If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1560If Emacs is displaying on an ordinary terminal or some other device which\n\
1561doesn't support multiple overlapping frames, this function does nothing.")
1562 (frame)
1563 Lisp_Object frame;
1564{
828ac693
RS
1565 if (NILP (frame))
1566 XSETFRAME (frame, selected_frame);
1567
dbc4e1c1 1568 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1569
1570 /* Do like the documentation says. */
1571 Fmake_frame_visible (frame);
1572
dbc4e1c1
JB
1573 if (frame_raise_lower_hook)
1574 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1575
1576 return Qnil;
1577}
1578
b49f5578 1579/* Should we have a corresponding function called Flower_Power? */
e518d5e1 1580DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
dbc4e1c1 1581 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1582If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1583If Emacs is displaying on an ordinary terminal or some other device which\n\
1584doesn't support multiple overlapping frames, this function does nothing.")
1585 (frame)
1586 Lisp_Object frame;
1587{
828ac693
RS
1588 if (NILP (frame))
1589 XSETFRAME (frame, selected_frame);
1590
dbc4e1c1
JB
1591 CHECK_LIVE_FRAME (frame, 0);
1592
1593 if (frame_raise_lower_hook)
1594 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1595
1596 return Qnil;
1597}
1598
d5e7c279 1599\f
ff11dfa1 1600DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1601 1, 2, 0,
ff11dfa1 1602 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1603In other words, switch-frame events caused by events in FRAME will\n\
1604request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1605FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1606\n\
a42e9724 1607If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1608cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1609\n\
a42e9724
JB
1610Focus redirection is useful for temporarily redirecting keystrokes to\n\
1611a surrogate minibuffer frame when a frame doesn't have its own\n\
1612minibuffer window.\n\
d5e7c279 1613\n\
a42e9724
JB
1614A frame's focus redirection can be changed by select-frame. If frame\n\
1615FOO is selected, and then a different frame BAR is selected, any\n\
1616frames redirecting their focus to FOO are shifted to redirect their\n\
1617focus to BAR. This allows focus redirection to work properly when the\n\
1618user switches from one frame to another using `select-window'.\n\
1619\n\
1620This means that a frame whose focus is redirected to itself is treated\n\
1621differently from a frame whose focus is redirected to nil; the former\n\
1622is affected by select-frame, while the latter is not.\n\
1623\n\
1624The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1625 (frame, focus_frame)
1626 Lisp_Object frame, focus_frame;
d5e7c279 1627{
13144095
JB
1628 /* Note that we don't check for a live frame here. It's reasonable
1629 to redirect the focus of a frame you're about to delete, if you
1630 know what other frame should receive those keystrokes. */
1631 CHECK_FRAME (frame, 0);
f9898cc6 1632
a42e9724 1633 if (! NILP (focus_frame))
ff11dfa1 1634 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1635
ff11dfa1 1636 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1637
ff11dfa1 1638 if (frame_rehighlight_hook)
dc0700f6 1639 (*frame_rehighlight_hook) (XFRAME (frame));
d5e7c279
JB
1640
1641 return Qnil;
1642}
1643
1644
ff11dfa1
JB
1645DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1646 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1647This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1648See `redirect-frame-focus'.")
1649 (frame)
1650 Lisp_Object frame;
d5e7c279 1651{
ff11dfa1 1652 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1653
ff11dfa1 1654 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1655}
1656
1657
dc6f92b8 1658\f
329ca574
RS
1659/* Return the value of frame parameter PROP in frame FRAME. */
1660
dc6f92b8 1661Lisp_Object
ff11dfa1
JB
1662get_frame_param (frame, prop)
1663 register struct frame *frame;
dc6f92b8
JB
1664 Lisp_Object prop;
1665{
1666 register Lisp_Object tem;
1667
ff11dfa1 1668 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1669 if (EQ (tem, Qnil))
1670 return tem;
1671 return Fcdr (tem);
1672}
1673
329ca574
RS
1674/* Return the buffer-predicate of the selected frame. */
1675
1676Lisp_Object
1677frame_buffer_predicate ()
1678{
1679 return selected_frame->buffer_predicate;
1680}
1681
fa54c6ae
RS
1682/* Return the buffer-list of the selected frame. */
1683
1684Lisp_Object
1685frame_buffer_list ()
1686{
1687 return selected_frame->buffer_list;
1688}
1689
1690/* Set the buffer-list of the selected frame. */
1691
1692void
1693set_frame_buffer_list (list)
1694 Lisp_Object list;
1695{
1696 selected_frame->buffer_list = list;
1697}
1698
1699/* Discard BUFFER from the buffer-list of each frame. */
1700
1701void
1702frames_discard_buffer (buffer)
1703 Lisp_Object buffer;
1704{
1705 Lisp_Object frame, tail;
1706
1707 FOR_EACH_FRAME (tail, frame)
1708 {
1709 XFRAME (frame)->buffer_list
1710 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1711 }
1712}
1713
214b3216
RS
1714/* Move BUFFER to the end of the buffer-list of each frame. */
1715
1716void
1717frames_bury_buffer (buffer)
1718 Lisp_Object buffer;
1719{
1720 Lisp_Object frame, tail;
1721
1722 FOR_EACH_FRAME (tail, frame)
1723 {
1724 XFRAME (frame)->buffer_list
1725 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1726 Fcons (buffer, Qnil));
1727 }
1728}
1729
329ca574
RS
1730/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1731 If the alist already has an element for PROP, we change it. */
1732
dc6f92b8 1733void
fd0c2bd1 1734store_in_alist (alistptr, prop, val)
dc6f92b8 1735 Lisp_Object *alistptr, val;
fd0c2bd1 1736 Lisp_Object prop;
dc6f92b8
JB
1737{
1738 register Lisp_Object tem;
dc6f92b8 1739
dc6f92b8
JB
1740 tem = Fassq (prop, *alistptr);
1741 if (EQ (tem, Qnil))
1742 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1743 else
1744 Fsetcdr (tem, val);
1745}
1746
1747void
ff11dfa1
JB
1748store_frame_param (f, prop, val)
1749 struct frame *f;
dc6f92b8
JB
1750 Lisp_Object prop, val;
1751{
1752 register Lisp_Object tem;
1753
fa54c6ae
RS
1754 if (EQ (prop, Qbuffer_list))
1755 {
1756 f->buffer_list = val;
1757 return;
1758 }
1759
ff11dfa1 1760 tem = Fassq (prop, f->param_alist);
dc6f92b8 1761 if (EQ (tem, Qnil))
ff11dfa1 1762 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1763 else
1764 Fsetcdr (tem, val);
bc93c097 1765
329ca574
RS
1766 if (EQ (prop, Qbuffer_predicate))
1767 f->buffer_predicate = val;
1768
032d78fe 1769 if (! FRAME_WINDOW_P (f))
7e63ac6a
RS
1770 if (EQ (prop, Qmenu_bar_lines))
1771 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
a249de79 1772
e35d291d 1773 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1774 {
1775 if (! MINI_WINDOW_P (XWINDOW (val)))
1776 error ("Surrogate minibuffer windows must be minibuffer windows.");
1777
7af7ef38
KH
1778 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1779 && !EQ (val, f->minibuffer_window))
1780 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1781
1782 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1783 f->minibuffer_window = val;
bc93c097 1784 }
dc6f92b8
JB
1785}
1786
ff11dfa1
JB
1787DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1788 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1789It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1790The meaningful PARMs depend on the kind of frame.\n\
1791If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1792 (frame)
1793 Lisp_Object frame;
dc6f92b8
JB
1794{
1795 Lisp_Object alist;
f769f1b2 1796 FRAME_PTR f;
dd10ec4f 1797 int height, width;
dc6f92b8 1798
ff11dfa1
JB
1799 if (EQ (frame, Qnil))
1800 f = selected_frame;
dc6f92b8
JB
1801 else
1802 {
ff11dfa1
JB
1803 CHECK_FRAME (frame, 0);
1804 f = XFRAME (frame);
dc6f92b8
JB
1805 }
1806
f769f1b2 1807 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1808 return Qnil;
1809
ff11dfa1 1810 alist = Fcopy_alist (f->param_alist);
bb221971
RS
1811#ifdef MSDOS
1812 if (FRAME_MSDOS_P (f))
1813 {
1814 static char *colornames[16] =
1815 {
1816 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1817 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1818 "lightred", "lightmagenta", "yellow", "white"
1819 };
1820 store_in_alist (&alist, intern ("foreground-color"),
1821 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1822 store_in_alist (&alist, intern ("background-color"),
1823 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1824 }
1825 store_in_alist (&alist, intern ("font"), build_string ("default"));
1826#endif
fd0c2bd1 1827 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
1828 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1829 store_in_alist (&alist, Qheight, make_number (height));
1830 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1831 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 1832 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1833 store_in_alist (&alist, Qminibuffer,
39acc701 1834 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1835 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1836 : FRAME_MINIBUF_WINDOW (f)));
1837 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fa54c6ae 1838 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
fd0c2bd1 1839
dbc4e1c1 1840 /* I think this should be done with a hook. */
032d78fe
GV
1841#ifdef HAVE_WINDOW_SYSTEM
1842 if (FRAME_WINDOW_P (f))
ff11dfa1 1843 x_report_frame_params (f, &alist);
b6dd20ed 1844 else
fd0c2bd1 1845#endif
16a3738c
KH
1846 {
1847 /* This ought to be correct in f->param_alist for an X frame. */
1848 Lisp_Object lines;
f4e93c40 1849 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1850 store_in_alist (&alist, Qmenu_bar_lines, lines);
1851 }
dc6f92b8
JB
1852 return alist;
1853}
1854
ff11dfa1
JB
1855DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1856 Smodify_frame_parameters, 2, 2, 0,
1857 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1858ALIST is an alist of parameters to change and their new values.\n\
1859Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
e80f3932
RS
1860The meaningful PARMs depend on the kind of frame.\n\
1861Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1862so that `frame-parameters' will return them.")
ff11dfa1
JB
1863 (frame, alist)
1864 Lisp_Object frame, alist;
dc6f92b8 1865{
fd0c2bd1 1866 FRAME_PTR f;
dc6f92b8
JB
1867 register Lisp_Object tail, elt, prop, val;
1868
ff11dfa1
JB
1869 if (EQ (frame, Qnil))
1870 f = selected_frame;
dc6f92b8
JB
1871 else
1872 {
ff11dfa1
JB
1873 CHECK_LIVE_FRAME (frame, 0);
1874 f = XFRAME (frame);
dc6f92b8
JB
1875 }
1876
dbc4e1c1 1877 /* I think this should be done with a hook. */
032d78fe
GV
1878#ifdef HAVE_WINDOW_SYSTEM
1879 if (FRAME_WINDOW_P (f))
fd0c2bd1 1880 x_set_frame_parameters (f, alist);
329ca574 1881 else
bb221971
RS
1882#endif
1883#ifdef MSDOS
1884 if (FRAME_MSDOS_P (f))
1885 IT_set_frame_parameters (f, alist);
1886 else
329ca574 1887#endif
41d44f1f
RS
1888 {
1889 int length = XINT (Flength (alist));
1890 int i;
1891 Lisp_Object *parms
1892 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1893 Lisp_Object *values
1894 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1895
1896 /* Extract parm names and values into those vectors. */
1897
1898 i = 0;
1899 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1900 {
1901 Lisp_Object elt, prop, val;
1902
1903 elt = Fcar (tail);
1904 parms[i] = Fcar (elt);
1905 values[i] = Fcdr (elt);
1906 i++;
1907 }
1908
1909 /* Now process them in reverse of specified order. */
1910 for (i--; i >= 0; i--)
1911 {
1912 prop = parms[i];
1913 val = values[i];
1914 store_frame_param (f, prop, val);
1915 }
1916 }
dc6f92b8
JB
1917
1918 return Qnil;
1919}
1920\f
a26a1f95
RS
1921DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1922 0, 1, 0,
1923 "Height in pixels of a line in the font in frame FRAME.\n\
1924If FRAME is omitted, the selected frame is used.\n\
1925For a terminal frame, the value is always 1.")
ff11dfa1
JB
1926 (frame)
1927 Lisp_Object frame;
dc6f92b8 1928{
a26a1f95 1929 struct frame *f;
dc6f92b8 1930
a26a1f95
RS
1931 if (NILP (frame))
1932 f = selected_frame;
1933 else
1934 {
1935 CHECK_FRAME (frame, 0);
1936 f = XFRAME (frame);
1937 }
1938
032d78fe
GV
1939#ifdef HAVE_WINDOW_SYSTEM
1940 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1941 return make_number (x_char_height (f));
1942 else
dc6d9681 1943#endif
a26a1f95
RS
1944 return make_number (1);
1945}
dc6d9681 1946
dc6f92b8 1947
a26a1f95
RS
1948DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1949 0, 1, 0,
1950 "Width in pixels of characters in the font in frame FRAME.\n\
1951If FRAME is omitted, the selected frame is used.\n\
1952The width is the same for all characters, because\n\
1953currently Emacs supports only fixed-width fonts.\n\
1954For a terminal screen, the value is always 1.")
1955 (frame)
1956 Lisp_Object frame;
dc6f92b8 1957{
a26a1f95
RS
1958 struct frame *f;
1959
1960 if (NILP (frame))
1961 f = selected_frame;
1962 else
1963 {
1964 CHECK_FRAME (frame, 0);
1965 f = XFRAME (frame);
1966 }
1967
032d78fe
GV
1968#ifdef HAVE_WINDOW_SYSTEM
1969 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1970 return make_number (x_char_width (f));
1971 else
1972#endif
1973 return make_number (1);
dc6f92b8
JB
1974}
1975
a26a1f95
RS
1976DEFUN ("frame-pixel-height", Fframe_pixel_height,
1977 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1978 "Return a FRAME's height in pixels.\n\
1979For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1980If FRAME is omitted, the selected frame is used.")
1981 (frame)
1982 Lisp_Object frame;
dc6f92b8 1983{
a26a1f95
RS
1984 struct frame *f;
1985
1986 if (NILP (frame))
1987 f = selected_frame;
1988 else
1989 {
1990 CHECK_FRAME (frame, 0);
1991 f = XFRAME (frame);
1992 }
1993
032d78fe
GV
1994#ifdef HAVE_WINDOW_SYSTEM
1995 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1996 return make_number (x_pixel_height (f));
1997 else
dc6d9681 1998#endif
a26a1f95
RS
1999 return make_number (FRAME_HEIGHT (f));
2000}
2001
2002DEFUN ("frame-pixel-width", Fframe_pixel_width,
2003 Sframe_pixel_width, 0, 1, 0,
2004 "Return FRAME's width in pixels.\n\
164a14ef 2005For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
2006If FRAME is omitted, the selected frame is used.")
2007 (frame)
2008 Lisp_Object frame;
2009{
2010 struct frame *f;
2011
2012 if (NILP (frame))
2013 f = selected_frame;
2014 else
2015 {
2016 CHECK_FRAME (frame, 0);
2017 f = XFRAME (frame);
2018 }
dc6f92b8 2019
032d78fe
GV
2020#ifdef HAVE_WINDOW_SYSTEM
2021 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2022 return make_number (x_pixel_width (f));
2023 else
2024#endif
2025 return make_number (FRAME_WIDTH (f));
2026}
2027\f
ff11dfa1
JB
2028DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2029 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 2030Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1 2031but that the idea of the actual height of the frame should not be changed.")
735eeca3
EN
2032 (frame, lines, pretend)
2033 Lisp_Object frame, lines, pretend;
dc6f92b8 2034{
ff11dfa1 2035 register struct frame *f;
dc6f92b8 2036
735eeca3 2037 CHECK_NUMBER (lines, 0);
ff11dfa1
JB
2038 if (NILP (frame))
2039 f = selected_frame;
dc6f92b8
JB
2040 else
2041 {
ff11dfa1
JB
2042 CHECK_LIVE_FRAME (frame, 0);
2043 f = XFRAME (frame);
dc6f92b8
JB
2044 }
2045
dbc4e1c1 2046 /* I think this should be done with a hook. */
032d78fe
GV
2047#ifdef HAVE_WINDOW_SYSTEM
2048 if (FRAME_WINDOW_P (f))
dc6f92b8 2049 {
735eeca3
EN
2050 if (XINT (lines) != f->height)
2051 x_set_window_size (f, 1, f->width, XINT (lines));
dc6f92b8
JB
2052 }
2053 else
fd0c2bd1 2054#endif
735eeca3 2055 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
dc6f92b8
JB
2056 return Qnil;
2057}
2058
ff11dfa1
JB
2059DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2060 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 2061Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
2062but that the idea of the actual width of the frame should not be changed.")
2063 (frame, cols, pretend)
fd0c2bd1 2064 Lisp_Object frame, cols, pretend;
dc6f92b8 2065{
ff11dfa1 2066 register struct frame *f;
dc6f92b8 2067 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
2068 if (NILP (frame))
2069 f = selected_frame;
dc6f92b8
JB
2070 else
2071 {
ff11dfa1
JB
2072 CHECK_LIVE_FRAME (frame, 0);
2073 f = XFRAME (frame);
dc6f92b8
JB
2074 }
2075
dbc4e1c1 2076 /* I think this should be done with a hook. */
032d78fe
GV
2077#ifdef HAVE_WINDOW_SYSTEM
2078 if (FRAME_WINDOW_P (f))
dc6f92b8 2079 {
ff11dfa1 2080 if (XINT (cols) != f->width)
808c0f20 2081 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
2082 }
2083 else
fd0c2bd1
JB
2084#endif
2085 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
2086 return Qnil;
2087}
2088
ff11dfa1
JB
2089DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2090 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2091 (frame, cols, rows)
2092 Lisp_Object frame, cols, rows;
dc6f92b8 2093{
ff11dfa1 2094 register struct frame *f;
dc6f92b8
JB
2095 int mask;
2096
ff11dfa1 2097 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2098 CHECK_NUMBER (cols, 2);
2099 CHECK_NUMBER (rows, 1);
ff11dfa1 2100 f = XFRAME (frame);
dc6f92b8 2101
dbc4e1c1 2102 /* I think this should be done with a hook. */
032d78fe
GV
2103#ifdef HAVE_WINDOW_SYSTEM
2104 if (FRAME_WINDOW_P (f))
dc6f92b8 2105 {
29824ce2
RS
2106 if (XINT (rows) != f->height || XINT (cols) != f->width
2107 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2108 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
2109 }
2110 else
fd0c2bd1
JB
2111#endif
2112 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
2113
2114 return Qnil;
2115}
2116
ff11dfa1
JB
2117DEFUN ("set-frame-position", Fset_frame_position,
2118 Sset_frame_position, 3, 3, 0,
2119 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
2120This is actually the position of the upper left corner of the frame.\n\
2121Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 2122the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
2123 (frame, xoffset, yoffset)
2124 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2125{
ff11dfa1 2126 register struct frame *f;
dc6f92b8
JB
2127 int mask;
2128
ff11dfa1 2129 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2130 CHECK_NUMBER (xoffset, 1);
2131 CHECK_NUMBER (yoffset, 2);
ff11dfa1 2132 f = XFRAME (frame);
dc6f92b8 2133
dbc4e1c1 2134 /* I think this should be done with a hook. */
032d78fe
GV
2135#ifdef HAVE_WINDOW_SYSTEM
2136 if (FRAME_WINDOW_P (f))
c7c70761 2137 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2138#endif
dc6f92b8
JB
2139
2140 return Qt;
2141}
dc6d9681 2142
dc6f92b8 2143\f
ff11dfa1 2144syms_of_frame ()
dc6f92b8 2145{
a249de79 2146 syms_of_frame_1 ();
dc6f92b8 2147
ff11dfa1 2148 staticpro (&Vframe_list);
dc6f92b8 2149
ff11dfa1
JB
2150 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2151 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
2152
2153 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 2154 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
2155 Vemacs_iconified = Qnil;
2156
c60f3a6a 2157 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
ff11dfa1 2158 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 2159\n\
ff11dfa1 2160Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
2161appropriate surrogate.\n\
2162\n\
2163Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 2164frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
2165minibuffer, no matter what this variable is set to. This means that\n\
2166this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 2167current set of frames, or where the minibuffer is currently being\n\
f9898cc6 2168displayed.");
dc6f92b8 2169
5add3885 2170 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2171 defsubr (&Sframep);
dbc4e1c1 2172 defsubr (&Sframe_live_p);
bb1513c9 2173 defsubr (&Smake_terminal_frame);
0f85737c 2174 defsubr (&Shandle_switch_frame);
1c212787 2175 defsubr (&Signore_event);
ff11dfa1
JB
2176 defsubr (&Sselect_frame);
2177 defsubr (&Sselected_frame);
2178 defsubr (&Swindow_frame);
2179 defsubr (&Sframe_root_window);
d446a856 2180 defsubr (&Sframe_first_window);
ff11dfa1 2181 defsubr (&Sframe_selected_window);
4a7cfafc 2182 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2183 defsubr (&Sframe_list);
2184 defsubr (&Snext_frame);
ef2c57ac 2185 defsubr (&Sprevious_frame);
ff11dfa1 2186 defsubr (&Sdelete_frame);
f9898cc6 2187 defsubr (&Smouse_position);
152e6c70 2188 defsubr (&Smouse_pixel_position);
dc6f92b8 2189 defsubr (&Sset_mouse_position);
152e6c70 2190 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2191#if 0
ff11dfa1
JB
2192 defsubr (&Sframe_configuration);
2193 defsubr (&Srestore_frame_configuration);
dc6f92b8 2194#endif
ff11dfa1
JB
2195 defsubr (&Smake_frame_visible);
2196 defsubr (&Smake_frame_invisible);
2197 defsubr (&Siconify_frame);
2198 defsubr (&Sframe_visible_p);
2199 defsubr (&Svisible_frame_list);
b49f5578
JB
2200 defsubr (&Sraise_frame);
2201 defsubr (&Slower_frame);
ff11dfa1
JB
2202 defsubr (&Sredirect_frame_focus);
2203 defsubr (&Sframe_focus);
2204 defsubr (&Sframe_parameters);
2205 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2206 defsubr (&Sframe_char_height);
2207 defsubr (&Sframe_char_width);
2208 defsubr (&Sframe_pixel_height);
2209 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2210 defsubr (&Sset_frame_height);
2211 defsubr (&Sset_frame_width);
2212 defsubr (&Sset_frame_size);
2213 defsubr (&Sset_frame_position);
dc6f92b8 2214}
e5d77022 2215
2f0b07e0
JB
2216keys_of_frame ()
2217{
0f85737c 2218 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 2219 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1c212787
KH
2220 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2221 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2f0b07e0 2222}