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