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