(customize-face-other-window): Make it work similarly.
[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
1a578e9b
AC
33#ifdef macintosh
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. */
296 if (XSTRING (Fbuffer_name (buf))->data[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
574a1a90 489#ifdef macintosh
1a578e9b
AC
490 make_mac_terminal_frame (f);
491#else
2d764c78 492 f->output_data.x = &tty_display;
1a578e9b 493#endif /* macintosh */
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
524#ifdef macintosh
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
AC
1114 if (NILP (force) && !other_visible_frames (f)
1115#ifdef macintosh
1116 /* Terminal frame deleted before any other visible frames are
1117 created. */
1118 && strcmp (XSTRING (f->name)->data, "F1") != 0
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
214b3216
RS
1821/* Move BUFFER to the end of the buffer-list of each frame. */
1822
1823void
1824frames_bury_buffer (buffer)
1825 Lisp_Object buffer;
1826{
1827 Lisp_Object frame, tail;
1828
1829 FOR_EACH_FRAME (tail, frame)
1830 {
835c1b36
GM
1831 struct frame *f = XFRAME (frame);
1832 Lisp_Object found;
1833
1834 found = Fmemq (buffer, f->buffer_list);
1835 if (!NILP (found))
1836 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1837 Fcons (buffer, Qnil));
214b3216
RS
1838 }
1839}
1840
329ca574
RS
1841/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1842 If the alist already has an element for PROP, we change it. */
1843
dc6f92b8 1844void
fd0c2bd1 1845store_in_alist (alistptr, prop, val)
dc6f92b8 1846 Lisp_Object *alistptr, val;
fd0c2bd1 1847 Lisp_Object prop;
dc6f92b8
JB
1848{
1849 register Lisp_Object tem;
dc6f92b8 1850
dc6f92b8
JB
1851 tem = Fassq (prop, *alistptr);
1852 if (EQ (tem, Qnil))
1853 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1854 else
1855 Fsetcdr (tem, val);
1856}
1857
e5317d61
EZ
1858static int
1859frame_name_fnn_p (str, len)
1860 char *str;
1861 int len;
1862{
1863 if (len > 1 && str[0] == 'F')
1864 {
1865 char *end_ptr;
e5317d61 1866
48970f2f
EZ
1867 strtol (str + 1, &end_ptr, 10);
1868
e5317d61
EZ
1869 if (end_ptr == str + len)
1870 return 1;
1871 }
1872 return 0;
1873}
1874
1875/* Set the name of the terminal frame. Also used by MSDOS frames.
1876 Modeled after x_set_name which is used for WINDOW frames. */
1877
1878void
1879set_term_frame_name (f, name)
1880 struct frame *f;
1881 Lisp_Object name;
1882{
1883 f->explicit_name = ! NILP (name);
1884
1885 /* If NAME is nil, set the name to F<num>. */
1886 if (NILP (name))
1887 {
1888 char namebuf[20];
1889
1890 /* Check for no change needed in this very common case
1891 before we do any consing. */
e34c5c7d 1892 if (frame_name_fnn_p (XSTRING (f->name)->data,
fc932ac6 1893 STRING_BYTES (XSTRING (f->name))))
e5317d61
EZ
1894 return;
1895
1896 terminal_frame_count++;
1897 sprintf (namebuf, "F%d", terminal_frame_count);
1898 name = build_string (namebuf);
1899 }
1900 else
1901 {
b7826503 1902 CHECK_STRING (name);
e5317d61
EZ
1903
1904 /* Don't change the name if it's already NAME. */
1905 if (! NILP (Fstring_equal (name, f->name)))
1906 return;
1907
1908 /* Don't allow the user to set the frame name to F<num>, so it
1909 doesn't clash with the names we generate for terminal frames. */
fc932ac6 1910 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
e5317d61
EZ
1911 error ("Frame names of the form F<num> are usurped by Emacs");
1912 }
1913
1914 f->name = name;
1915 update_mode_lines = 1;
1916}
1917
dc6f92b8 1918void
ff11dfa1
JB
1919store_frame_param (f, prop, val)
1920 struct frame *f;
dc6f92b8
JB
1921 Lisp_Object prop, val;
1922{
7eb63b72 1923 register Lisp_Object old_alist_elt;
dc6f92b8 1924
7eb63b72
GM
1925 /* The buffer-alist parameter is stored in a special place and is
1926 not in the alist. */
fa54c6ae
RS
1927 if (EQ (prop, Qbuffer_list))
1928 {
1929 f->buffer_list = val;
1930 return;
1931 }
1932
7eb63b72
GM
1933 /* If PROP is a symbol which is supposed to have frame-local values,
1934 and it is set up based on this frame, switch to the global
1935 binding. That way, we can create or alter the frame-local binding
1936 without messing up the symbol's status. */
1937 if (SYMBOLP (prop))
1938 {
1939 Lisp_Object valcontents;
f5c1dd0d 1940 valcontents = SYMBOL_VALUE (prop);
7eb63b72
GM
1941 if ((BUFFER_LOCAL_VALUEP (valcontents)
1942 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1943 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1944 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1945 swap_in_global_binding (prop);
1946 }
1947
94674d18
EZ
1948#ifndef WINDOWSNT
1949 /* The tty color mode needs to be set before the frame's parameter
1950 alist is updated with the new value, because set_tty_color_mode
1951 wants to look at the old mode. */
1952 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode))
1953 set_tty_color_mode (f, val);
1954#endif
1955
7eb63b72
GM
1956 /* Update the frame parameter alist. */
1957 old_alist_elt = Fassq (prop, f->param_alist);
1958 if (EQ (old_alist_elt, Qnil))
ff11dfa1 1959 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8 1960 else
7eb63b72 1961 Fsetcdr (old_alist_elt, val);
bc93c097 1962
7eb63b72
GM
1963 /* Update some other special parameters in their special places
1964 in addition to the alist. */
1965
329ca574
RS
1966 if (EQ (prop, Qbuffer_predicate))
1967 f->buffer_predicate = val;
1968
032d78fe 1969 if (! FRAME_WINDOW_P (f))
e5317d61
EZ
1970 {
1971 if (EQ (prop, Qmenu_bar_lines))
1972 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1973 else if (EQ (prop, Qname))
1974 set_term_frame_name (f, val);
1975 }
a249de79 1976
e35d291d 1977 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1978 {
1979 if (! MINI_WINDOW_P (XWINDOW (val)))
1980 error ("Surrogate minibuffer windows must be minibuffer windows.");
1981
213bac8a 1982 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
7af7ef38
KH
1983 && !EQ (val, f->minibuffer_window))
1984 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1985
1986 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1987 f->minibuffer_window = val;
bc93c097 1988 }
dc6f92b8
JB
1989}
1990
ff11dfa1 1991DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
14ff1ee0
PJ
1992 doc: /* Return the parameters-alist of frame FRAME.
1993It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
1994The meaningful PARMs depend on the kind of frame.
1995If FRAME is omitted, return information on the currently selected frame. */)
1996 (frame)
ff11dfa1 1997 Lisp_Object frame;
dc6f92b8
JB
1998{
1999 Lisp_Object alist;
f769f1b2 2000 FRAME_PTR f;
dd10ec4f 2001 int height, width;
57629833 2002 struct gcpro gcpro1;
dc6f92b8 2003
03390a72 2004 if (NILP (frame))
8d2666fe
GM
2005 frame = selected_frame;
2006
b7826503 2007 CHECK_FRAME (frame);
8d2666fe 2008 f = XFRAME (frame);
dc6f92b8 2009
f769f1b2 2010 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
2011 return Qnil;
2012
ff11dfa1 2013 alist = Fcopy_alist (f->param_alist);
57629833
GM
2014 GCPRO1 (alist);
2015
2d764c78 2016 if (!FRAME_WINDOW_P (f))
bb221971 2017 {
4aec4b29
EZ
2018 int fg = FRAME_FOREGROUND_PIXEL (f);
2019 int bg = FRAME_BACKGROUND_PIXEL (f);
e1d0bbc9
EZ
2020 Lisp_Object elt;
2021
2022 /* If the frame's parameter alist says the colors are
2023 unspecified and reversed, take the frame's background pixel
2024 for foreground and vice versa. */
2025 elt = Fassq (Qforeground_color, alist);
70de9f06
EZ
2026 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2027 {
2028 if (strncmp (XSTRING (XCDR (elt))->data,
2029 unspecified_bg,
2030 XSTRING (XCDR (elt))->size) == 0)
2031 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2032 else if (strncmp (XSTRING (XCDR (elt))->data,
2033 unspecified_fg,
2034 XSTRING (XCDR (elt))->size) == 0)
2035 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2036 }
e1d0bbc9
EZ
2037 else
2038 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2039 elt = Fassq (Qbackground_color, alist);
70de9f06
EZ
2040 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2041 {
2042 if (strncmp (XSTRING (XCDR (elt))->data,
2043 unspecified_fg,
2044 XSTRING (XCDR (elt))->size) == 0)
2045 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2046 else if (strncmp (XSTRING (XCDR (elt))->data,
2047 unspecified_bg,
2048 XSTRING (XCDR (elt))->size) == 0)
2049 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2050 }
e1d0bbc9
EZ
2051 else
2052 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2d764c78
EZ
2053 store_in_alist (&alist, intern ("font"),
2054 build_string (FRAME_MSDOS_P (f)
2055 ? "ms-dos"
4ec0d3c1 2056 : FRAME_W32_P (f) ? "w32term"
4ec0d3c1 2057 :"tty"));
bb221971 2058 }
fd0c2bd1 2059 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
2060 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2061 store_in_alist (&alist, Qheight, make_number (height));
2062 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2063 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 2064 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 2065 store_in_alist (&alist, Qminibuffer,
39acc701 2066 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
2067 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2068 : FRAME_MINIBUF_WINDOW (f)));
2069 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
03390a72 2070 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
fd0c2bd1 2071
dbc4e1c1 2072 /* I think this should be done with a hook. */
032d78fe
GV
2073#ifdef HAVE_WINDOW_SYSTEM
2074 if (FRAME_WINDOW_P (f))
ff11dfa1 2075 x_report_frame_params (f, &alist);
b6dd20ed 2076 else
fd0c2bd1 2077#endif
16a3738c
KH
2078 {
2079 /* This ought to be correct in f->param_alist for an X frame. */
2080 Lisp_Object lines;
f4e93c40 2081 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
2082 store_in_alist (&alist, Qmenu_bar_lines, lines);
2083 }
57629833
GM
2084
2085 UNGCPRO;
dc6f92b8
JB
2086 return alist;
2087}
2088
8b60f7bc
GM
2089
2090DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
14ff1ee0
PJ
2091 doc: /* Return FRAME's value for parameter PARAMETER.
2092If FRAME is nil, describe the currently selected frame. */)
2093 (frame, parameter)
2094 Lisp_Object frame, parameter;
8b60f7bc
GM
2095{
2096 struct frame *f;
2097 Lisp_Object value;
2098
2099 if (NILP (frame))
2100 frame = selected_frame;
2101 else
b7826503
PJ
2102 CHECK_FRAME (frame);
2103 CHECK_SYMBOL (parameter);
8b60f7bc
GM
2104
2105 f = XFRAME (frame);
2106 value = Qnil;
2107
2108 if (FRAME_LIVE_P (f))
2109 {
5cd62b8c 2110 /* Avoid consing in frequent cases. */
67d853e6
GM
2111 if (EQ (parameter, Qname))
2112 value = f->name;
6345f6aa
GM
2113#ifdef HAVE_X_WINDOWS
2114 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2115 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2116#endif /* HAVE_X_WINDOWS */
75700ff2
GM
2117 else if (EQ (parameter, Qbackground_color)
2118 || EQ (parameter, Qforeground_color))
67d853e6
GM
2119 {
2120 value = Fassq (parameter, f->param_alist);
2121 if (CONSP (value))
5f65b39d 2122 {
5f65b39d
EZ
2123 value = XCDR (value);
2124 /* Fframe_parameters puts the actual fg/bg color names,
2125 even if f->param_alist says otherwise. This is
2126 important when param_alist's notion of colors is
2127 "unspecified". We need to do the same here. */
2128 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2129 {
e1d0bbc9
EZ
2130 char *color_name;
2131 EMACS_INT csz;
2132
2133 if (EQ (parameter, Qbackground_color))
2134 {
2135 color_name = XSTRING (value)->data;
2136 csz = XSTRING (value)->size;
2137 if (strncmp (color_name, unspecified_bg, csz) == 0)
2138 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2139 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2140 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2141 }
2142 else if (EQ (parameter, Qforeground_color))
2143 {
2144 color_name = XSTRING (value)->data;
2145 csz = XSTRING (value)->size;
2146 if (strncmp (color_name, unspecified_fg, csz) == 0)
2147 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2148 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2149 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2150 }
5f65b39d
EZ
2151 }
2152 }
b23236fb
EZ
2153 else
2154 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
67d853e6 2155 }
75700ff2
GM
2156 else if (EQ (parameter, Qdisplay_type)
2157 || EQ (parameter, Qbackground_mode))
75700ff2
GM
2158 value = Fcdr (Fassq (parameter, f->param_alist));
2159 else
2160 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
8b60f7bc
GM
2161 }
2162
2163 return value;
2164}
2165
2166
ff11dfa1
JB
2167DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2168 Smodify_frame_parameters, 2, 2, 0,
14ff1ee0
PJ
2169 doc: /* Modify the parameters of frame FRAME according to ALIST.
2170If FRAME is nil, it defaults to the selected frame.
2171ALIST is an alist of parameters to change and their new values.
2172Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2173The meaningful PARMs depend on the kind of frame.
2174Undefined PARMs are ignored, but stored in the frame's parameter list
2175so that `frame-parameters' will return them.
2176
2177The value of frame parameter FOO can also be accessed
2178as a frame-local binding for the variable FOO, if you have
2179enabled such bindings for that variable with `make-variable-frame-local'. */)
2180 (frame, alist)
ff11dfa1 2181 Lisp_Object frame, alist;
dc6f92b8 2182{
fd0c2bd1 2183 FRAME_PTR f;
213bac8a 2184 register Lisp_Object tail, prop, val;
3df1fda2
GM
2185 int count = BINDING_STACK_SIZE ();
2186
2187 /* Bind this to t to inhibit initialization of the default face from
2188 X resources in face-set-after-frame-default. If we don't inhibit
2189 this, modifying the `font' frame parameter, for example, while
2190 there is a `default.attributeFont' X resource, won't work,
2191 because `default's font is reset to the value of the X resource
2192 and that resets the `font' frame parameter. */
2193 specbind (Qinhibit_default_face_x_resources, Qt);
dc6f92b8 2194
ff11dfa1 2195 if (EQ (frame, Qnil))
8d2666fe 2196 frame = selected_frame;
b7826503 2197 CHECK_LIVE_FRAME (frame);
8d2666fe 2198 f = XFRAME (frame);
dc6f92b8 2199
dbc4e1c1 2200 /* I think this should be done with a hook. */
032d78fe
GV
2201#ifdef HAVE_WINDOW_SYSTEM
2202 if (FRAME_WINDOW_P (f))
fd0c2bd1 2203 x_set_frame_parameters (f, alist);
329ca574 2204 else
bb221971
RS
2205#endif
2206#ifdef MSDOS
2207 if (FRAME_MSDOS_P (f))
2208 IT_set_frame_parameters (f, alist);
2209 else
329ca574 2210#endif
574a1a90 2211
41d44f1f
RS
2212 {
2213 int length = XINT (Flength (alist));
2214 int i;
2215 Lisp_Object *parms
2216 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2217 Lisp_Object *values
2218 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2219
2220 /* Extract parm names and values into those vectors. */
2221
2222 i = 0;
2223 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2224 {
213bac8a 2225 Lisp_Object elt;
41d44f1f
RS
2226
2227 elt = Fcar (tail);
2228 parms[i] = Fcar (elt);
2229 values[i] = Fcdr (elt);
2230 i++;
2231 }
2232
2233 /* Now process them in reverse of specified order. */
2234 for (i--; i >= 0; i--)
2235 {
2236 prop = parms[i];
2237 val = values[i];
2238 store_frame_param (f, prop, val);
2239 }
2240 }
dc6f92b8 2241
3df1fda2 2242 return unbind_to (count, Qnil);
dc6f92b8
JB
2243}
2244\f
a26a1f95 2245DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
14ff1ee0
PJ
2246 0, 1, 0,
2247 doc: /* Height in pixels of a line in the font in frame FRAME.
2248If FRAME is omitted, the selected frame is used.
2249For a terminal frame, the value is always 1. */)
ff11dfa1
JB
2250 (frame)
2251 Lisp_Object frame;
dc6f92b8 2252{
a26a1f95 2253 struct frame *f;
dc6f92b8 2254
a26a1f95 2255 if (NILP (frame))
8d2666fe 2256 frame = selected_frame;
b7826503 2257 CHECK_FRAME (frame);
8d2666fe 2258 f = XFRAME (frame);
a26a1f95 2259
032d78fe
GV
2260#ifdef HAVE_WINDOW_SYSTEM
2261 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2262 return make_number (x_char_height (f));
2263 else
dc6d9681 2264#endif
a26a1f95
RS
2265 return make_number (1);
2266}
dc6d9681 2267
dc6f92b8 2268
a26a1f95 2269DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
14ff1ee0
PJ
2270 0, 1, 0,
2271 doc: /* Width in pixels of characters in the font in frame FRAME.
2272If FRAME is omitted, the selected frame is used.
2273The width is the same for all characters, because
2274currently Emacs supports only fixed-width fonts.
2275For a terminal screen, the value is always 1. */)
2276 (frame)
a26a1f95 2277 Lisp_Object frame;
dc6f92b8 2278{
a26a1f95
RS
2279 struct frame *f;
2280
2281 if (NILP (frame))
8d2666fe 2282 frame = selected_frame;
b7826503 2283 CHECK_FRAME (frame);
8d2666fe 2284 f = XFRAME (frame);
a26a1f95 2285
032d78fe
GV
2286#ifdef HAVE_WINDOW_SYSTEM
2287 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2288 return make_number (x_char_width (f));
2289 else
2290#endif
2291 return make_number (1);
dc6f92b8
JB
2292}
2293
a26a1f95
RS
2294DEFUN ("frame-pixel-height", Fframe_pixel_height,
2295 Sframe_pixel_height, 0, 1, 0,
14ff1ee0
PJ
2296 doc: /* Return a FRAME's height in pixels.
2297This counts only the height available for text lines,
2298not menu bars on window-system Emacs frames.
2299For a terminal frame, the result really gives the height in characters.
2300If FRAME is omitted, the selected frame is used. */)
2301 (frame)
a26a1f95 2302 Lisp_Object frame;
dc6f92b8 2303{
a26a1f95
RS
2304 struct frame *f;
2305
2306 if (NILP (frame))
8d2666fe 2307 frame = selected_frame;
b7826503 2308 CHECK_FRAME (frame);
8d2666fe 2309 f = XFRAME (frame);
a26a1f95 2310
032d78fe
GV
2311#ifdef HAVE_WINDOW_SYSTEM
2312 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2313 return make_number (x_pixel_height (f));
2314 else
dc6d9681 2315#endif
a26a1f95
RS
2316 return make_number (FRAME_HEIGHT (f));
2317}
2318
2319DEFUN ("frame-pixel-width", Fframe_pixel_width,
2320 Sframe_pixel_width, 0, 1, 0,
14ff1ee0
PJ
2321 doc: /* Return FRAME's width in pixels.
2322For a terminal frame, the result really gives the width in characters.
2323If FRAME is omitted, the selected frame is used. */)
2324 (frame)
a26a1f95
RS
2325 Lisp_Object frame;
2326{
2327 struct frame *f;
2328
2329 if (NILP (frame))
8d2666fe 2330 frame = selected_frame;
b7826503 2331 CHECK_FRAME (frame);
8d2666fe 2332 f = XFRAME (frame);
dc6f92b8 2333
032d78fe
GV
2334#ifdef HAVE_WINDOW_SYSTEM
2335 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2336 return make_number (x_pixel_width (f));
2337 else
2338#endif
2339 return make_number (FRAME_WIDTH (f));
2340}
2341\f
ff11dfa1 2342DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
14ff1ee0
PJ
2343 doc: /* Specify that the frame FRAME has LINES lines.
2344Optional third arg non-nil means that redisplay should use LINES lines
2345but that the idea of the actual height of the frame should not be changed. */)
2346 (frame, lines, pretend)
735eeca3 2347 Lisp_Object frame, lines, pretend;
dc6f92b8 2348{
ff11dfa1 2349 register struct frame *f;
dc6f92b8 2350
b7826503 2351 CHECK_NUMBER (lines);
ff11dfa1 2352 if (NILP (frame))
8d2666fe 2353 frame = selected_frame;
b7826503 2354 CHECK_LIVE_FRAME (frame);
8d2666fe 2355 f = XFRAME (frame);
dc6f92b8 2356
dbc4e1c1 2357 /* I think this should be done with a hook. */
032d78fe
GV
2358#ifdef HAVE_WINDOW_SYSTEM
2359 if (FRAME_WINDOW_P (f))
dc6f92b8 2360 {
735eeca3
EN
2361 if (XINT (lines) != f->height)
2362 x_set_window_size (f, 1, f->width, XINT (lines));
32347cf4 2363 do_pending_window_change (0);
dc6f92b8
JB
2364 }
2365 else
fd0c2bd1 2366#endif
32347cf4 2367 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
dc6f92b8
JB
2368 return Qnil;
2369}
2370
ff11dfa1 2371DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
14ff1ee0
PJ
2372 doc: /* Specify that the frame FRAME has COLS columns.
2373Optional third arg non-nil means that redisplay should use COLS columns
2374but that the idea of the actual width of the frame should not be changed. */)
2375 (frame, cols, pretend)
fd0c2bd1 2376 Lisp_Object frame, cols, pretend;
dc6f92b8 2377{
ff11dfa1 2378 register struct frame *f;
b7826503 2379 CHECK_NUMBER (cols);
ff11dfa1 2380 if (NILP (frame))
8d2666fe 2381 frame = selected_frame;
b7826503 2382 CHECK_LIVE_FRAME (frame);
8d2666fe 2383 f = XFRAME (frame);
dc6f92b8 2384
dbc4e1c1 2385 /* I think this should be done with a hook. */
032d78fe
GV
2386#ifdef HAVE_WINDOW_SYSTEM
2387 if (FRAME_WINDOW_P (f))
dc6f92b8 2388 {
ff11dfa1 2389 if (XINT (cols) != f->width)
808c0f20 2390 x_set_window_size (f, 1, XINT (cols), f->height);
32347cf4 2391 do_pending_window_change (0);
dc6f92b8
JB
2392 }
2393 else
fd0c2bd1 2394#endif
32347cf4 2395 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
dc6f92b8
JB
2396 return Qnil;
2397}
2398
ff11dfa1 2399DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
14ff1ee0
PJ
2400 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2401 (frame, cols, rows)
ff11dfa1 2402 Lisp_Object frame, cols, rows;
dc6f92b8 2403{
ff11dfa1 2404 register struct frame *f;
dc6f92b8 2405
b7826503
PJ
2406 CHECK_LIVE_FRAME (frame);
2407 CHECK_NUMBER (cols);
2408 CHECK_NUMBER (rows);
ff11dfa1 2409 f = XFRAME (frame);
dc6f92b8 2410
dbc4e1c1 2411 /* I think this should be done with a hook. */
032d78fe
GV
2412#ifdef HAVE_WINDOW_SYSTEM
2413 if (FRAME_WINDOW_P (f))
dc6f92b8 2414 {
29824ce2
RS
2415 if (XINT (rows) != f->height || XINT (cols) != f->width
2416 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2417 x_set_window_size (f, 1, XINT (cols), XINT (rows));
32347cf4 2418 do_pending_window_change (0);
dc6f92b8
JB
2419 }
2420 else
fd0c2bd1 2421#endif
32347cf4 2422 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
dc6f92b8
JB
2423
2424 return Qnil;
2425}
2426
ff11dfa1
JB
2427DEFUN ("set-frame-position", Fset_frame_position,
2428 Sset_frame_position, 3, 3, 0,
14ff1ee0
PJ
2429 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2430This is actually the position of the upper left corner of the frame.
2431Negative values for XOFFSET or YOFFSET are interpreted relative to
2432the rightmost or bottommost possible position (that stays within the screen). */)
2433 (frame, xoffset, yoffset)
ff11dfa1 2434 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2435{
ff11dfa1 2436 register struct frame *f;
dc6f92b8 2437
b7826503
PJ
2438 CHECK_LIVE_FRAME (frame);
2439 CHECK_NUMBER (xoffset);
2440 CHECK_NUMBER (yoffset);
ff11dfa1 2441 f = XFRAME (frame);
dc6f92b8 2442
dbc4e1c1 2443 /* I think this should be done with a hook. */
032d78fe
GV
2444#ifdef HAVE_WINDOW_SYSTEM
2445 if (FRAME_WINDOW_P (f))
c7c70761 2446 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2447#endif
dc6f92b8
JB
2448
2449 return Qt;
2450}
dc6d9681 2451
dc6f92b8 2452\f
dfcf069d 2453void
ff11dfa1 2454syms_of_frame ()
dc6f92b8 2455{
3df1fda2
GM
2456 Qframep = intern ("framep");
2457 staticpro (&Qframep);
2458 Qframe_live_p = intern ("frame-live-p");
2459 staticpro (&Qframe_live_p);
2460 Qheight = intern ("height");
2461 staticpro (&Qheight);
2462 Qicon = intern ("icon");
2463 staticpro (&Qicon);
2464 Qminibuffer = intern ("minibuffer");
2465 staticpro (&Qminibuffer);
2466 Qmodeline = intern ("modeline");
2467 staticpro (&Qmodeline);
2468 Qname = intern ("name");
2469 staticpro (&Qname);
2470 Qonly = intern ("only");
2471 staticpro (&Qonly);
2472 Qunsplittable = intern ("unsplittable");
2473 staticpro (&Qunsplittable);
2474 Qmenu_bar_lines = intern ("menu-bar-lines");
2475 staticpro (&Qmenu_bar_lines);
2476 Qtool_bar_lines = intern ("tool-bar-lines");
2477 staticpro (&Qtool_bar_lines);
2478 Qwidth = intern ("width");
2479 staticpro (&Qwidth);
2480 Qx = intern ("x");
2481 staticpro (&Qx);
2482 Qw32 = intern ("w32");
2483 staticpro (&Qw32);
2484 Qpc = intern ("pc");
2485 staticpro (&Qpc);
2486 Qmac = intern ("mac");
2487 staticpro (&Qmac);
2488 Qvisible = intern ("visible");
2489 staticpro (&Qvisible);
2490 Qbuffer_predicate = intern ("buffer-predicate");
2491 staticpro (&Qbuffer_predicate);
2492 Qbuffer_list = intern ("buffer-list");
2493 staticpro (&Qbuffer_list);
2494 Qtitle = intern ("title");
2495 staticpro (&Qtitle);
2496 Qdisplay_type = intern ("display-type");
2497 staticpro (&Qdisplay_type);
2498 Qbackground_mode = intern ("background-mode");
2499 staticpro (&Qbackground_mode);
82ee92ea
KS
2500 Qleft_fringe = intern ("left-fringe");
2501 staticpro (&Qleft_fringe);
2502 Qright_fringe = intern ("right-fringe");
2503 staticpro (&Qright_fringe);
94674d18
EZ
2504 Qtty_color_mode = intern ("tty-color-mode");
2505 staticpro (&Qtty_color_mode);
dc6f92b8 2506
3df1fda2 2507 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
14ff1ee0
PJ
2508 doc: /* Alist of default values for frame creation.
2509These may be set in your init file, like this:
2510 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))
2511These override values given in window system configuration data,
2512 including X Windows' defaults database.
2513For values specific to the first Emacs frame, see `initial-frame-alist'.
2514For values specific to the separate minibuffer frame, see
2515 `minibuffer-frame-alist'.
2516The `menu-bar-lines' element of the list controls whether new frames
67334131 2517 have menu bars; `menu-bar-mode' works by altering this element.
3cf54801 2518Setting this variable does not affect existing frames, only new ones. */);
3df1fda2
GM
2519 Vdefault_frame_alist = Qnil;
2520
2521 Qinhibit_default_face_x_resources
2522 = intern ("inhibit-default-face-x-resources");
2523 staticpro (&Qinhibit_default_face_x_resources);
dc6f92b8 2524
ff11dfa1 2525 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
14ff1ee0 2526 doc: /* The initial frame-object, which represents Emacs's stdout. */);
dc6f92b8
JB
2527
2528 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
14ff1ee0 2529 doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */);
dc6f92b8
JB
2530 Vemacs_iconified = Qnil;
2531
beb0bc36 2532 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
14ff1ee0
PJ
2533 doc: /* If non-nil, function to transform normal value of `mouse-position'.
2534`mouse-position' calls this function, passing its usual return value as
2535argument, and returns whatever this function returns.
2536This abnormal hook exists for the benefit of packages like `xt-mouse.el'
2537which need to do mouse handling at the Lisp level. */);
beb0bc36
DL
2538 Vmouse_position_function = Qnil;
2539
6018080f
KS
2540 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
2541 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
2542If the value is an integer, highlighting is only shown after moving the
2543mouse, while keyboard input turns off the highlight even when the mouse
2544is over the clickable text. However, the mouse shape still indicates
2545when the mouse is over clickable text. */);
2a28d471 2546 Vmouse_highlight = Qt;
6018080f 2547
c60f3a6a 2548 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
14ff1ee0
PJ
2549 doc: /* Minibufferless frames use this frame's minibuffer.
2550
2551Emacs cannot create minibufferless frames unless this is set to an
2552appropriate surrogate.
2553
2554Emacs consults this variable only when creating minibufferless
2555frames; once the frame is created, it sticks with its assigned
2556minibuffer, no matter what this variable is set to. This means that
2557this variable doesn't necessarily say anything meaningful about the
2558current set of frames, or where the minibuffer is currently being
2559displayed.
2560
2561This variable is local to the current terminal and cannot be buffer-local. */);
dc6f92b8 2562
3df1fda2
GM
2563 staticpro (&Vframe_list);
2564
5add3885 2565 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2566 defsubr (&Sframep);
dbc4e1c1 2567 defsubr (&Sframe_live_p);
bb1513c9 2568 defsubr (&Smake_terminal_frame);
0f85737c 2569 defsubr (&Shandle_switch_frame);
1c212787 2570 defsubr (&Signore_event);
ff11dfa1
JB
2571 defsubr (&Sselect_frame);
2572 defsubr (&Sselected_frame);
2573 defsubr (&Swindow_frame);
2574 defsubr (&Sframe_root_window);
d446a856 2575 defsubr (&Sframe_first_window);
ff11dfa1 2576 defsubr (&Sframe_selected_window);
4a7cfafc 2577 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2578 defsubr (&Sframe_list);
2579 defsubr (&Snext_frame);
ef2c57ac 2580 defsubr (&Sprevious_frame);
ff11dfa1 2581 defsubr (&Sdelete_frame);
f9898cc6 2582 defsubr (&Smouse_position);
152e6c70 2583 defsubr (&Smouse_pixel_position);
dc6f92b8 2584 defsubr (&Sset_mouse_position);
152e6c70 2585 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2586#if 0
ff11dfa1
JB
2587 defsubr (&Sframe_configuration);
2588 defsubr (&Srestore_frame_configuration);
dc6f92b8 2589#endif
ff11dfa1
JB
2590 defsubr (&Smake_frame_visible);
2591 defsubr (&Smake_frame_invisible);
2592 defsubr (&Siconify_frame);
2593 defsubr (&Sframe_visible_p);
2594 defsubr (&Svisible_frame_list);
b49f5578
JB
2595 defsubr (&Sraise_frame);
2596 defsubr (&Slower_frame);
ff11dfa1
JB
2597 defsubr (&Sredirect_frame_focus);
2598 defsubr (&Sframe_focus);
2599 defsubr (&Sframe_parameters);
8b60f7bc 2600 defsubr (&Sframe_parameter);
ff11dfa1 2601 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2602 defsubr (&Sframe_char_height);
2603 defsubr (&Sframe_char_width);
2604 defsubr (&Sframe_pixel_height);
2605 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2606 defsubr (&Sset_frame_height);
2607 defsubr (&Sset_frame_width);
2608 defsubr (&Sset_frame_size);
2609 defsubr (&Sset_frame_position);
dc6f92b8 2610}