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