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