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