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