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