(get_user_app): Free the gethomedir value.
[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));
d2bee99e 1168
71025e5e
KH
1169#ifdef HAVE_WINDOW_SYSTEM
1170 /* Free all fontset data. */
1171 free_fontset_data (FRAME_FONTSET_DATA (f));
1172#endif
1173
8678b9cc
JB
1174 /* Since some events are handled at the interrupt level, we may get
1175 an event for f at any time; if we zero out the frame's display
1176 now, then we may trip up the event-handling code. Instead, we'll
1177 promise that the display of the frame must be valid until we have
1178 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
1179
1180 /* I think this should be done with a hook. */
032d78fe
GV
1181#ifdef HAVE_WINDOW_SYSTEM
1182 if (FRAME_WINDOW_P (f))
8678b9cc 1183 x_destroy_window (f);
d5e7c279
JB
1184#endif
1185
7556890b 1186 f->output_data.nothing = 0;
8678b9cc 1187
ff11dfa1 1188 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1189 another one. */
ff11dfa1 1190 if (f == last_nonminibuf_frame)
d5e7c279 1191 {
ff11dfa1 1192 Lisp_Object frames;
1113d9db 1193
ff11dfa1 1194 last_nonminibuf_frame = 0;
d5e7c279 1195
ff11dfa1
JB
1196 for (frames = Vframe_list;
1197 CONSP (frames);
1198 frames = XCONS (frames)->cdr)
d5e7c279 1199 {
ff11dfa1
JB
1200 f = XFRAME (XCONS (frames)->car);
1201 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1202 {
ff11dfa1 1203 last_nonminibuf_frame = f;
d5e7c279
JB
1204 break;
1205 }
1206 }
1207 }
dc6f92b8 1208
c4c6d073
KH
1209 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1210 find another one. Prefer minibuffer-only frames, but also notice
1211 frames with other windows. */
c60f3a6a 1212 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1113d9db 1213 {
ff11dfa1 1214 Lisp_Object frames;
1113d9db 1215
ff11dfa1 1216 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1217 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1218 /* Some frame we found on the same kboard, or nil if there are none. */
1219 Lisp_Object frame_on_same_kboard;
1113d9db 1220
32fda9ba 1221 frame_on_same_kboard = Qnil;
ab9f008d 1222 frame_with_minibuf = Qnil;
32fda9ba 1223
ff11dfa1
JB
1224 for (frames = Vframe_list;
1225 CONSP (frames);
1226 frames = XCONS (frames)->cdr)
1113d9db 1227 {
ab9f008d 1228 Lisp_Object this;
c4c6d073 1229 struct frame *f1;
1113d9db 1230
ab9f008d 1231 this = XCONS (frames)->car;
e35d291d 1232 if (!FRAMEP (this))
1113d9db 1233 abort ();
c4c6d073 1234 f1 = XFRAME (this);
1113d9db 1235
c4c6d073
KH
1236 /* Consider only frames on the same kboard
1237 and only those with minibuffers. */
1238 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1239 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1240 {
ff11dfa1 1241 frame_with_minibuf = this;
c4c6d073 1242 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1243 break;
1244 }
32fda9ba
RS
1245
1246 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1247 frame_on_same_kboard = this;
1113d9db
JB
1248 }
1249
32fda9ba
RS
1250 if (!NILP (frame_on_same_kboard))
1251 {
1252 /* We know that there must be some frame with a minibuffer out
1253 there. If this were not true, all of the frames present
1254 would have to be minibufferless, which implies that at some
1255 point their minibuffer frames must have been deleted, but
1256 that is prohibited at the top; you can't delete surrogate
1257 minibuffer frames. */
1258 if (NILP (frame_with_minibuf))
1259 abort ();
1113d9db 1260
32fda9ba
RS
1261 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1262 }
1263 else
1264 /* No frames left on this kboard--say no minibuffer either. */
1265 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1266 }
1267
e681c92a
RS
1268 /* Cause frame titles to update--necessary if we now have just one frame. */
1269 update_mode_lines = 1;
1270
dc6f92b8
JB
1271 return Qnil;
1272}
1273\f
1274/* Return mouse position in character cell units. */
1275
f9898cc6 1276DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1277 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1278The position is given in character cells, where (0, 0) is the\n\
1279upper-left corner.\n\
f9898cc6 1280If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1281to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1282and nil for X and Y.")
1283 ()
dc6f92b8 1284{
ff11dfa1 1285 FRAME_PTR f;
dbc4e1c1 1286 Lisp_Object lispy_dummy;
fd2777e0 1287 enum scroll_bar_part party_dummy;
dbc4e1c1 1288 Lisp_Object x, y;
5384466a 1289 int col, row;
dbc4e1c1 1290 unsigned long long_dummy;
dc6f92b8 1291
c5074d8c
RS
1292 f = selected_frame;
1293 x = y = Qnil;
1294
f443c170 1295#ifdef HAVE_MOUSE
c5074d8c 1296 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1297 if (mouse_position_hook)
0c5c1cf7 1298 (*mouse_position_hook) (&f, 0,
dbc4e1c1
JB
1299 &lispy_dummy, &party_dummy,
1300 &x, &y,
1301 &long_dummy);
76db7eb4
KH
1302 if (! NILP (x))
1303 {
1304 col = XINT (x);
1305 row = XINT (y);
8126c3b4 1306 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1307 XSETINT (x, col);
1308 XSETINT (y, row);
1309 }
f443c170 1310#endif
2d80a27a 1311 XSETFRAME (lispy_dummy, f);
c5074d8c 1312 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1313}
1314
152e6c70
RS
1315DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1316 Smouse_pixel_position, 0, 0, 0,
1317 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1318The position is given in pixel units, where (0, 0) is the\n\
1319upper-left corner.\n\
1320If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1321to read the mouse position, it returns the selected frame for FRAME\n\
1322and nil for X and Y.")
1323 ()
1324{
1325 FRAME_PTR f;
1326 Lisp_Object lispy_dummy;
1327 enum scroll_bar_part party_dummy;
1328 Lisp_Object x, y;
1329 int col, row;
1330 unsigned long long_dummy;
1331
1332 f = selected_frame;
1333 x = y = Qnil;
1334
0c5c1cf7 1335#ifdef HAVE_MOUSE
152e6c70
RS
1336 /* It's okay for the hook to refrain from storing anything. */
1337 if (mouse_position_hook)
0c5c1cf7 1338 (*mouse_position_hook) (&f, 0,
152e6c70
RS
1339 &lispy_dummy, &party_dummy,
1340 &x, &y,
1341 &long_dummy);
0c5c1cf7 1342#endif
2d80a27a 1343 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1344 return Fcons (lispy_dummy, Fcons (x, y));
1345}
1346
dc6f92b8 1347DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1348 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
efb57f43
RS
1349Note, this is a no-op for an X frame that is not visible.\n\
1350If you have just created a frame, you must wait for it to become visible\n\
1351before calling this function on it, like this.\n\
1352 (while (not (frame-visible-p frame)) (sleep-for .5))")
ff11dfa1
JB
1353 (frame, x, y)
1354 Lisp_Object frame, x, y;
dc6f92b8 1355{
ff11dfa1 1356 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1357 CHECK_NUMBER (x, 2);
1358 CHECK_NUMBER (y, 1);
1359
dbc4e1c1 1360 /* I think this should be done with a hook. */
032d78fe
GV
1361#ifdef HAVE_WINDOW_SYSTEM
1362 if (FRAME_WINDOW_P (XFRAME (frame)))
dc6f92b8 1363 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1364 x_set_mouse_position (XFRAME (frame), x, y);
bb221971 1365#else
be625e00 1366#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1367 if (FRAME_MSDOS_P (XFRAME (frame)))
1368 {
1369 Fselect_frame (frame, Qnil);
1370 mouse_moveto (XINT (x), XINT (y));
1371 }
1372#endif
dc6f92b8
JB
1373#endif
1374
1375 return Qnil;
1376}
152e6c70
RS
1377
1378DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1379 Sset_mouse_pixel_position, 3, 3, 0,
1380 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
efb57f43
RS
1381Note, this is a no-op for an X frame that is not visible.\n\
1382If you have just created a frame, you must wait for it to become visible\n\
1383before calling this function on it, like this.\n\
1384 (while (not (frame-visible-p frame)) (sleep-for .5))")
152e6c70
RS
1385 (frame, x, y)
1386 Lisp_Object frame, x, y;
1387{
1388 CHECK_LIVE_FRAME (frame, 0);
1389 CHECK_NUMBER (x, 2);
1390 CHECK_NUMBER (y, 1);
1391
1392 /* I think this should be done with a hook. */
032d78fe
GV
1393#ifdef HAVE_WINDOW_SYSTEM
1394 if (FRAME_WINDOW_P (XFRAME (frame)))
152e6c70
RS
1395 /* Warping the mouse will cause enternotify and focus events. */
1396 x_set_mouse_pixel_position (XFRAME (frame), x, y);
bb221971 1397#else
be625e00 1398#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1399 if (FRAME_MSDOS_P (XFRAME (frame)))
1400 {
1401 Fselect_frame (frame, Qnil);
1402 mouse_moveto (XINT (x), XINT (y));
1403 }
1404#endif
152e6c70
RS
1405#endif
1406
1407 return Qnil;
1408}
dc6f92b8 1409\f
ff11dfa1 1410DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1411 0, 1, "",
ff11dfa1 1412 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1413If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1414 (frame)
1415 Lisp_Object frame;
dc6f92b8 1416{
1aa66088 1417 if (NILP (frame))
2d80a27a 1418 XSETFRAME (frame, selected_frame);
1aa66088 1419
ff11dfa1 1420 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1421
dbc4e1c1 1422 /* I think this should be done with a hook. */
032d78fe
GV
1423#ifdef HAVE_WINDOW_SYSTEM
1424 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1425 {
1426 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1427 x_make_frame_visible (XFRAME (frame));
1428 }
fd0c2bd1 1429#endif
dc6f92b8 1430
565620a5
RS
1431 /* Make menu bar update for the Buffers and Frams menus. */
1432 windows_or_buffers_changed++;
1433
ff11dfa1 1434 return frame;
dc6f92b8
JB
1435}
1436
ff11dfa1 1437DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1438 0, 2, "",
8693ca83 1439 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1440If omitted, FRAME defaults to the currently selected frame.\n\
1441Normally you may not make FRAME invisible if all other frames are invisible,\n\
1442but if the second optional argument FORCE is non-nil, you may do so.")
1443 (frame, force)
1444 Lisp_Object frame, force;
dc6f92b8 1445{
1aa66088 1446 if (NILP (frame))
2d80a27a 1447 XSETFRAME (frame, selected_frame);
1aa66088 1448
ff11dfa1 1449 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1450
808c0f20
RS
1451 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1452 error ("Attempt to make invisible the sole visible or iconified frame");
1453
3d378fdf 1454#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1455 /* Don't let the frame remain selected. */
1456 if (XFRAME (frame) == selected_frame)
61f94483 1457 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
3d378fdf 1458#endif
9c394f17
RS
1459
1460 /* Don't allow minibuf_window to remain on a deleted frame. */
1461 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1462 {
1463 Fset_window_buffer (selected_frame->minibuffer_window,
1464 XWINDOW (minibuf_window)->buffer);
1465 minibuf_window = selected_frame->minibuffer_window;
1466 }
1467
dbc4e1c1 1468 /* I think this should be done with a hook. */
032d78fe
GV
1469#ifdef HAVE_WINDOW_SYSTEM
1470 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1471 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1472#endif
dc6f92b8 1473
565620a5
RS
1474 /* Make menu bar update for the Buffers and Frams menus. */
1475 windows_or_buffers_changed++;
1476
dc6f92b8
JB
1477 return Qnil;
1478}
1479
ff11dfa1 1480DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1481 0, 1, "",
8693ca83
JB
1482 "Make the frame FRAME into an icon.\n\
1483If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1484 (frame)
1485 Lisp_Object frame;
dc6f92b8 1486{
1aa66088 1487 if (NILP (frame))
2d80a27a 1488 XSETFRAME (frame, selected_frame);
1aa66088 1489
ff11dfa1 1490 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1491
3d378fdf 1492#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1493 /* Don't let the frame remain selected. */
1494 if (XFRAME (frame) == selected_frame)
1495 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1496#endif
9c394f17
RS
1497
1498 /* Don't allow minibuf_window to remain on a deleted frame. */
1499 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1500 {
1501 Fset_window_buffer (selected_frame->minibuffer_window,
1502 XWINDOW (minibuf_window)->buffer);
1503 minibuf_window = selected_frame->minibuffer_window;
1504 }
1505
dbc4e1c1 1506 /* I think this should be done with a hook. */
032d78fe
GV
1507#ifdef HAVE_WINDOW_SYSTEM
1508 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1509 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1510#endif
dc6f92b8 1511
565620a5
RS
1512 /* Make menu bar update for the Buffers and Frams menus. */
1513 windows_or_buffers_changed++;
1514
dc6f92b8
JB
1515 return Qnil;
1516}
1517
ff11dfa1 1518DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1519 1, 1, 0,
ff11dfa1
JB
1520 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1521A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1522a window system, it may not show at all.\n\
fd0c2bd1 1523Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1524 (frame)
1525 Lisp_Object frame;
dc6f92b8 1526{
ff11dfa1 1527 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1528
5c044f55
RS
1529 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1530
a42e9724 1531 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1532 return Qt;
a42e9724 1533 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1534 return Qicon;
dc6f92b8
JB
1535 return Qnil;
1536}
1537
ff11dfa1 1538DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1539 0, 0, 0,
ff11dfa1 1540 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1541 ()
1542{
ff11dfa1
JB
1543 Lisp_Object tail, frame;
1544 struct frame *f;
dc6f92b8
JB
1545 Lisp_Object value;
1546
1547 value = Qnil;
ff11dfa1 1548 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1549 {
ff11dfa1 1550 frame = XCONS (tail)->car;
e35d291d 1551 if (!FRAMEP (frame))
dc6f92b8 1552 continue;
ff11dfa1 1553 f = XFRAME (frame);
a42e9724 1554 if (FRAME_VISIBLE_P (f))
ff11dfa1 1555 value = Fcons (frame, value);
dc6f92b8
JB
1556 }
1557 return value;
1558}
d5e7c279
JB
1559
1560
e518d5e1 1561DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
dbc4e1c1
JB
1562 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1563If FRAME is invisible, make it visible.\n\
828ac693 1564If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1565If Emacs is displaying on an ordinary terminal or some other device which\n\
1566doesn't support multiple overlapping frames, this function does nothing.")
1567 (frame)
1568 Lisp_Object frame;
1569{
828ac693
RS
1570 if (NILP (frame))
1571 XSETFRAME (frame, selected_frame);
1572
dbc4e1c1 1573 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1574
1575 /* Do like the documentation says. */
1576 Fmake_frame_visible (frame);
1577
dbc4e1c1
JB
1578 if (frame_raise_lower_hook)
1579 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1580
1581 return Qnil;
1582}
1583
b49f5578 1584/* Should we have a corresponding function called Flower_Power? */
e518d5e1 1585DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
dbc4e1c1 1586 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1587If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1588If Emacs is displaying on an ordinary terminal or some other device which\n\
1589doesn't support multiple overlapping frames, this function does nothing.")
1590 (frame)
1591 Lisp_Object frame;
1592{
828ac693
RS
1593 if (NILP (frame))
1594 XSETFRAME (frame, selected_frame);
1595
dbc4e1c1
JB
1596 CHECK_LIVE_FRAME (frame, 0);
1597
1598 if (frame_raise_lower_hook)
1599 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1600
1601 return Qnil;
1602}
1603
d5e7c279 1604\f
ff11dfa1 1605DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1606 1, 2, 0,
ff11dfa1 1607 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1608In other words, switch-frame events caused by events in FRAME will\n\
1609request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1610FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1611\n\
a42e9724 1612If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1613cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1614\n\
a42e9724
JB
1615Focus redirection is useful for temporarily redirecting keystrokes to\n\
1616a surrogate minibuffer frame when a frame doesn't have its own\n\
1617minibuffer window.\n\
d5e7c279 1618\n\
a42e9724
JB
1619A frame's focus redirection can be changed by select-frame. If frame\n\
1620FOO is selected, and then a different frame BAR is selected, any\n\
1621frames redirecting their focus to FOO are shifted to redirect their\n\
1622focus to BAR. This allows focus redirection to work properly when the\n\
1623user switches from one frame to another using `select-window'.\n\
1624\n\
1625This means that a frame whose focus is redirected to itself is treated\n\
1626differently from a frame whose focus is redirected to nil; the former\n\
1627is affected by select-frame, while the latter is not.\n\
1628\n\
1629The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1630 (frame, focus_frame)
1631 Lisp_Object frame, focus_frame;
d5e7c279 1632{
13144095
JB
1633 /* Note that we don't check for a live frame here. It's reasonable
1634 to redirect the focus of a frame you're about to delete, if you
1635 know what other frame should receive those keystrokes. */
1636 CHECK_FRAME (frame, 0);
f9898cc6 1637
a42e9724 1638 if (! NILP (focus_frame))
ff11dfa1 1639 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1640
ff11dfa1 1641 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1642
ff11dfa1 1643 if (frame_rehighlight_hook)
dc0700f6 1644 (*frame_rehighlight_hook) (XFRAME (frame));
d5e7c279
JB
1645
1646 return Qnil;
1647}
1648
1649
ff11dfa1
JB
1650DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1651 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1652This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1653See `redirect-frame-focus'.")
1654 (frame)
1655 Lisp_Object frame;
d5e7c279 1656{
ff11dfa1 1657 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1658
ff11dfa1 1659 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1660}
1661
1662
dc6f92b8 1663\f
329ca574
RS
1664/* Return the value of frame parameter PROP in frame FRAME. */
1665
dc6f92b8 1666Lisp_Object
ff11dfa1
JB
1667get_frame_param (frame, prop)
1668 register struct frame *frame;
dc6f92b8
JB
1669 Lisp_Object prop;
1670{
1671 register Lisp_Object tem;
1672
ff11dfa1 1673 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1674 if (EQ (tem, Qnil))
1675 return tem;
1676 return Fcdr (tem);
1677}
1678
329ca574
RS
1679/* Return the buffer-predicate of the selected frame. */
1680
1681Lisp_Object
1682frame_buffer_predicate ()
1683{
1684 return selected_frame->buffer_predicate;
1685}
1686
fa54c6ae
RS
1687/* Return the buffer-list of the selected frame. */
1688
1689Lisp_Object
1690frame_buffer_list ()
1691{
1692 return selected_frame->buffer_list;
1693}
1694
1695/* Set the buffer-list of the selected frame. */
1696
1697void
1698set_frame_buffer_list (list)
1699 Lisp_Object list;
1700{
1701 selected_frame->buffer_list = list;
1702}
1703
1704/* Discard BUFFER from the buffer-list of each frame. */
1705
1706void
1707frames_discard_buffer (buffer)
1708 Lisp_Object buffer;
1709{
1710 Lisp_Object frame, tail;
1711
1712 FOR_EACH_FRAME (tail, frame)
1713 {
1714 XFRAME (frame)->buffer_list
1715 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1716 }
1717}
1718
214b3216
RS
1719/* Move BUFFER to the end of the buffer-list of each frame. */
1720
1721void
1722frames_bury_buffer (buffer)
1723 Lisp_Object buffer;
1724{
1725 Lisp_Object frame, tail;
1726
1727 FOR_EACH_FRAME (tail, frame)
1728 {
1729 XFRAME (frame)->buffer_list
1730 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1731 Fcons (buffer, Qnil));
1732 }
1733}
1734
329ca574
RS
1735/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1736 If the alist already has an element for PROP, we change it. */
1737
dc6f92b8 1738void
fd0c2bd1 1739store_in_alist (alistptr, prop, val)
dc6f92b8 1740 Lisp_Object *alistptr, val;
fd0c2bd1 1741 Lisp_Object prop;
dc6f92b8
JB
1742{
1743 register Lisp_Object tem;
dc6f92b8 1744
dc6f92b8
JB
1745 tem = Fassq (prop, *alistptr);
1746 if (EQ (tem, Qnil))
1747 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1748 else
1749 Fsetcdr (tem, val);
1750}
1751
1752void
ff11dfa1
JB
1753store_frame_param (f, prop, val)
1754 struct frame *f;
dc6f92b8
JB
1755 Lisp_Object prop, val;
1756{
1757 register Lisp_Object tem;
1758
fa54c6ae
RS
1759 if (EQ (prop, Qbuffer_list))
1760 {
1761 f->buffer_list = val;
1762 return;
1763 }
1764
ff11dfa1 1765 tem = Fassq (prop, f->param_alist);
dc6f92b8 1766 if (EQ (tem, Qnil))
ff11dfa1 1767 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1768 else
1769 Fsetcdr (tem, val);
bc93c097 1770
329ca574
RS
1771 if (EQ (prop, Qbuffer_predicate))
1772 f->buffer_predicate = val;
1773
032d78fe 1774 if (! FRAME_WINDOW_P (f))
7e63ac6a
RS
1775 if (EQ (prop, Qmenu_bar_lines))
1776 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
a249de79 1777
e35d291d 1778 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1779 {
1780 if (! MINI_WINDOW_P (XWINDOW (val)))
1781 error ("Surrogate minibuffer windows must be minibuffer windows.");
1782
7af7ef38
KH
1783 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1784 && !EQ (val, f->minibuffer_window))
1785 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1786
1787 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1788 f->minibuffer_window = val;
bc93c097 1789 }
dc6f92b8
JB
1790}
1791
ff11dfa1
JB
1792DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1793 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1794It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1795The meaningful PARMs depend on the kind of frame.\n\
1796If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1797 (frame)
1798 Lisp_Object frame;
dc6f92b8
JB
1799{
1800 Lisp_Object alist;
f769f1b2 1801 FRAME_PTR f;
dd10ec4f 1802 int height, width;
dc6f92b8 1803
ff11dfa1
JB
1804 if (EQ (frame, Qnil))
1805 f = selected_frame;
dc6f92b8
JB
1806 else
1807 {
ff11dfa1
JB
1808 CHECK_FRAME (frame, 0);
1809 f = XFRAME (frame);
dc6f92b8
JB
1810 }
1811
f769f1b2 1812 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1813 return Qnil;
1814
ff11dfa1 1815 alist = Fcopy_alist (f->param_alist);
bb221971
RS
1816#ifdef MSDOS
1817 if (FRAME_MSDOS_P (f))
1818 {
1819 static char *colornames[16] =
1820 {
1821 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1822 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1823 "lightred", "lightmagenta", "yellow", "white"
1824 };
1825 store_in_alist (&alist, intern ("foreground-color"),
1826 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
1827 store_in_alist (&alist, intern ("background-color"),
1828 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
1829 }
1830 store_in_alist (&alist, intern ("font"), build_string ("default"));
1831#endif
fd0c2bd1 1832 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
1833 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
1834 store_in_alist (&alist, Qheight, make_number (height));
1835 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
1836 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 1837 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1838 store_in_alist (&alist, Qminibuffer,
39acc701 1839 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1840 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1841 : FRAME_MINIBUF_WINDOW (f)));
1842 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fa54c6ae 1843 store_in_alist (&alist, Qbuffer_list, frame_buffer_list ());
fd0c2bd1 1844
dbc4e1c1 1845 /* I think this should be done with a hook. */
032d78fe
GV
1846#ifdef HAVE_WINDOW_SYSTEM
1847 if (FRAME_WINDOW_P (f))
ff11dfa1 1848 x_report_frame_params (f, &alist);
b6dd20ed 1849 else
fd0c2bd1 1850#endif
16a3738c
KH
1851 {
1852 /* This ought to be correct in f->param_alist for an X frame. */
1853 Lisp_Object lines;
f4e93c40 1854 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1855 store_in_alist (&alist, Qmenu_bar_lines, lines);
1856 }
dc6f92b8
JB
1857 return alist;
1858}
1859
ff11dfa1
JB
1860DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1861 Smodify_frame_parameters, 2, 2, 0,
1862 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1863ALIST is an alist of parameters to change and their new values.\n\
1864Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
e80f3932
RS
1865The meaningful PARMs depend on the kind of frame.\n\
1866Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1867so that `frame-parameters' will return them.")
ff11dfa1
JB
1868 (frame, alist)
1869 Lisp_Object frame, alist;
dc6f92b8 1870{
fd0c2bd1 1871 FRAME_PTR f;
dc6f92b8
JB
1872 register Lisp_Object tail, elt, prop, val;
1873
ff11dfa1
JB
1874 if (EQ (frame, Qnil))
1875 f = selected_frame;
dc6f92b8
JB
1876 else
1877 {
ff11dfa1
JB
1878 CHECK_LIVE_FRAME (frame, 0);
1879 f = XFRAME (frame);
dc6f92b8
JB
1880 }
1881
dbc4e1c1 1882 /* I think this should be done with a hook. */
032d78fe
GV
1883#ifdef HAVE_WINDOW_SYSTEM
1884 if (FRAME_WINDOW_P (f))
fd0c2bd1 1885 x_set_frame_parameters (f, alist);
329ca574 1886 else
bb221971
RS
1887#endif
1888#ifdef MSDOS
1889 if (FRAME_MSDOS_P (f))
1890 IT_set_frame_parameters (f, alist);
1891 else
329ca574 1892#endif
41d44f1f
RS
1893 {
1894 int length = XINT (Flength (alist));
1895 int i;
1896 Lisp_Object *parms
1897 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1898 Lisp_Object *values
1899 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
1900
1901 /* Extract parm names and values into those vectors. */
1902
1903 i = 0;
1904 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
1905 {
1906 Lisp_Object elt, prop, val;
1907
1908 elt = Fcar (tail);
1909 parms[i] = Fcar (elt);
1910 values[i] = Fcdr (elt);
1911 i++;
1912 }
1913
1914 /* Now process them in reverse of specified order. */
1915 for (i--; i >= 0; i--)
1916 {
1917 prop = parms[i];
1918 val = values[i];
1919 store_frame_param (f, prop, val);
1920 }
1921 }
dc6f92b8
JB
1922
1923 return Qnil;
1924}
1925\f
a26a1f95
RS
1926DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1927 0, 1, 0,
1928 "Height in pixels of a line in the font in frame FRAME.\n\
1929If FRAME is omitted, the selected frame is used.\n\
1930For a terminal frame, the value is always 1.")
ff11dfa1
JB
1931 (frame)
1932 Lisp_Object frame;
dc6f92b8 1933{
a26a1f95 1934 struct frame *f;
dc6f92b8 1935
a26a1f95
RS
1936 if (NILP (frame))
1937 f = selected_frame;
1938 else
1939 {
1940 CHECK_FRAME (frame, 0);
1941 f = XFRAME (frame);
1942 }
1943
032d78fe
GV
1944#ifdef HAVE_WINDOW_SYSTEM
1945 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1946 return make_number (x_char_height (f));
1947 else
dc6d9681 1948#endif
a26a1f95
RS
1949 return make_number (1);
1950}
dc6d9681 1951
dc6f92b8 1952
a26a1f95
RS
1953DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1954 0, 1, 0,
1955 "Width in pixels of characters in the font in frame FRAME.\n\
1956If FRAME is omitted, the selected frame is used.\n\
1957The width is the same for all characters, because\n\
1958currently Emacs supports only fixed-width fonts.\n\
1959For a terminal screen, the value is always 1.")
1960 (frame)
1961 Lisp_Object frame;
dc6f92b8 1962{
a26a1f95
RS
1963 struct frame *f;
1964
1965 if (NILP (frame))
1966 f = selected_frame;
1967 else
1968 {
1969 CHECK_FRAME (frame, 0);
1970 f = XFRAME (frame);
1971 }
1972
032d78fe
GV
1973#ifdef HAVE_WINDOW_SYSTEM
1974 if (FRAME_WINDOW_P (f))
a26a1f95
RS
1975 return make_number (x_char_width (f));
1976 else
1977#endif
1978 return make_number (1);
dc6f92b8
JB
1979}
1980
a26a1f95
RS
1981DEFUN ("frame-pixel-height", Fframe_pixel_height,
1982 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1983 "Return a FRAME's height in pixels.\n\
1984For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1985If FRAME is omitted, the selected frame is used.")
1986 (frame)
1987 Lisp_Object frame;
dc6f92b8 1988{
a26a1f95
RS
1989 struct frame *f;
1990
1991 if (NILP (frame))
1992 f = selected_frame;
1993 else
1994 {
1995 CHECK_FRAME (frame, 0);
1996 f = XFRAME (frame);
1997 }
1998
032d78fe
GV
1999#ifdef HAVE_WINDOW_SYSTEM
2000 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2001 return make_number (x_pixel_height (f));
2002 else
dc6d9681 2003#endif
a26a1f95
RS
2004 return make_number (FRAME_HEIGHT (f));
2005}
2006
2007DEFUN ("frame-pixel-width", Fframe_pixel_width,
2008 Sframe_pixel_width, 0, 1, 0,
2009 "Return FRAME's width in pixels.\n\
164a14ef 2010For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
2011If FRAME is omitted, the selected frame is used.")
2012 (frame)
2013 Lisp_Object frame;
2014{
2015 struct frame *f;
2016
2017 if (NILP (frame))
2018 f = selected_frame;
2019 else
2020 {
2021 CHECK_FRAME (frame, 0);
2022 f = XFRAME (frame);
2023 }
dc6f92b8 2024
032d78fe
GV
2025#ifdef HAVE_WINDOW_SYSTEM
2026 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2027 return make_number (x_pixel_width (f));
2028 else
2029#endif
2030 return make_number (FRAME_WIDTH (f));
2031}
2032\f
ff11dfa1
JB
2033DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2034 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 2035Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1 2036but that the idea of the actual height of the frame should not be changed.")
735eeca3
EN
2037 (frame, lines, pretend)
2038 Lisp_Object frame, lines, pretend;
dc6f92b8 2039{
ff11dfa1 2040 register struct frame *f;
dc6f92b8 2041
735eeca3 2042 CHECK_NUMBER (lines, 0);
ff11dfa1
JB
2043 if (NILP (frame))
2044 f = selected_frame;
dc6f92b8
JB
2045 else
2046 {
ff11dfa1
JB
2047 CHECK_LIVE_FRAME (frame, 0);
2048 f = XFRAME (frame);
dc6f92b8
JB
2049 }
2050
dbc4e1c1 2051 /* I think this should be done with a hook. */
032d78fe
GV
2052#ifdef HAVE_WINDOW_SYSTEM
2053 if (FRAME_WINDOW_P (f))
dc6f92b8 2054 {
735eeca3
EN
2055 if (XINT (lines) != f->height)
2056 x_set_window_size (f, 1, f->width, XINT (lines));
dc6f92b8
JB
2057 }
2058 else
fd0c2bd1 2059#endif
735eeca3 2060 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0);
dc6f92b8
JB
2061 return Qnil;
2062}
2063
ff11dfa1
JB
2064DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2065 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 2066Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
2067but that the idea of the actual width of the frame should not be changed.")
2068 (frame, cols, pretend)
fd0c2bd1 2069 Lisp_Object frame, cols, pretend;
dc6f92b8 2070{
ff11dfa1 2071 register struct frame *f;
dc6f92b8 2072 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
2073 if (NILP (frame))
2074 f = selected_frame;
dc6f92b8
JB
2075 else
2076 {
ff11dfa1
JB
2077 CHECK_LIVE_FRAME (frame, 0);
2078 f = XFRAME (frame);
dc6f92b8
JB
2079 }
2080
dbc4e1c1 2081 /* I think this should be done with a hook. */
032d78fe
GV
2082#ifdef HAVE_WINDOW_SYSTEM
2083 if (FRAME_WINDOW_P (f))
dc6f92b8 2084 {
ff11dfa1 2085 if (XINT (cols) != f->width)
808c0f20 2086 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
2087 }
2088 else
fd0c2bd1
JB
2089#endif
2090 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
2091 return Qnil;
2092}
2093
ff11dfa1
JB
2094DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2095 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2096 (frame, cols, rows)
2097 Lisp_Object frame, cols, rows;
dc6f92b8 2098{
ff11dfa1 2099 register struct frame *f;
dc6f92b8
JB
2100 int mask;
2101
ff11dfa1 2102 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2103 CHECK_NUMBER (cols, 2);
2104 CHECK_NUMBER (rows, 1);
ff11dfa1 2105 f = XFRAME (frame);
dc6f92b8 2106
dbc4e1c1 2107 /* I think this should be done with a hook. */
032d78fe
GV
2108#ifdef HAVE_WINDOW_SYSTEM
2109 if (FRAME_WINDOW_P (f))
dc6f92b8 2110 {
29824ce2
RS
2111 if (XINT (rows) != f->height || XINT (cols) != f->width
2112 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2113 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
2114 }
2115 else
fd0c2bd1
JB
2116#endif
2117 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
2118
2119 return Qnil;
2120}
2121
ff11dfa1
JB
2122DEFUN ("set-frame-position", Fset_frame_position,
2123 Sset_frame_position, 3, 3, 0,
2124 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
2125This is actually the position of the upper left corner of the frame.\n\
2126Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 2127the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
2128 (frame, xoffset, yoffset)
2129 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2130{
ff11dfa1 2131 register struct frame *f;
dc6f92b8
JB
2132 int mask;
2133
ff11dfa1 2134 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2135 CHECK_NUMBER (xoffset, 1);
2136 CHECK_NUMBER (yoffset, 2);
ff11dfa1 2137 f = XFRAME (frame);
dc6f92b8 2138
dbc4e1c1 2139 /* I think this should be done with a hook. */
032d78fe
GV
2140#ifdef HAVE_WINDOW_SYSTEM
2141 if (FRAME_WINDOW_P (f))
c7c70761 2142 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2143#endif
dc6f92b8
JB
2144
2145 return Qt;
2146}
dc6d9681 2147
dc6f92b8 2148\f
ff11dfa1 2149syms_of_frame ()
dc6f92b8 2150{
a249de79 2151 syms_of_frame_1 ();
dc6f92b8 2152
ff11dfa1 2153 staticpro (&Vframe_list);
dc6f92b8 2154
ff11dfa1
JB
2155 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2156 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
2157
2158 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 2159 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
2160 Vemacs_iconified = Qnil;
2161
c60f3a6a 2162 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
ff11dfa1 2163 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 2164\n\
ff11dfa1 2165Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
2166appropriate surrogate.\n\
2167\n\
2168Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 2169frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
2170minibuffer, no matter what this variable is set to. This means that\n\
2171this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 2172current set of frames, or where the minibuffer is currently being\n\
f9898cc6 2173displayed.");
dc6f92b8 2174
5add3885 2175 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2176 defsubr (&Sframep);
dbc4e1c1 2177 defsubr (&Sframe_live_p);
bb1513c9 2178 defsubr (&Smake_terminal_frame);
0f85737c 2179 defsubr (&Shandle_switch_frame);
1c212787 2180 defsubr (&Signore_event);
ff11dfa1
JB
2181 defsubr (&Sselect_frame);
2182 defsubr (&Sselected_frame);
2183 defsubr (&Swindow_frame);
2184 defsubr (&Sframe_root_window);
d446a856 2185 defsubr (&Sframe_first_window);
ff11dfa1 2186 defsubr (&Sframe_selected_window);
4a7cfafc 2187 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2188 defsubr (&Sframe_list);
2189 defsubr (&Snext_frame);
ef2c57ac 2190 defsubr (&Sprevious_frame);
ff11dfa1 2191 defsubr (&Sdelete_frame);
f9898cc6 2192 defsubr (&Smouse_position);
152e6c70 2193 defsubr (&Smouse_pixel_position);
dc6f92b8 2194 defsubr (&Sset_mouse_position);
152e6c70 2195 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2196#if 0
ff11dfa1
JB
2197 defsubr (&Sframe_configuration);
2198 defsubr (&Srestore_frame_configuration);
dc6f92b8 2199#endif
ff11dfa1
JB
2200 defsubr (&Smake_frame_visible);
2201 defsubr (&Smake_frame_invisible);
2202 defsubr (&Siconify_frame);
2203 defsubr (&Sframe_visible_p);
2204 defsubr (&Svisible_frame_list);
b49f5578
JB
2205 defsubr (&Sraise_frame);
2206 defsubr (&Slower_frame);
ff11dfa1
JB
2207 defsubr (&Sredirect_frame_focus);
2208 defsubr (&Sframe_focus);
2209 defsubr (&Sframe_parameters);
2210 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2211 defsubr (&Sframe_char_height);
2212 defsubr (&Sframe_char_width);
2213 defsubr (&Sframe_pixel_height);
2214 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2215 defsubr (&Sset_frame_height);
2216 defsubr (&Sset_frame_width);
2217 defsubr (&Sset_frame_size);
2218 defsubr (&Sset_frame_position);
dc6f92b8 2219}
e5d77022 2220
2f0b07e0
JB
2221keys_of_frame ()
2222{
0f85737c 2223 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 2224 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1c212787
KH
2225 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2226 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2f0b07e0 2227}