(Fmake_terminal_frame): Use SELECTED_FRAME.
[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
JB
1048{
1049 Lisp_Object tail;
1050
ff11dfa1 1051 if (NILP (frame))
8d2666fe
GM
1052 frame = selected_frame;
1053
1054 CHECK_LIVE_FRAME (frame, 0);
ff11dfa1 1055 return next_frame (frame, miniframe);
dc6f92b8 1056}
dbc4e1c1 1057
ef2c57ac
RM
1058DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1059 "Return the previous frame in the frame list before FRAME.\n\
06537cc8 1060It considers only frames on the same terminal as FRAME.\n\
ef2c57ac
RM
1061By default, skip minibuffer-only frames.\n\
1062If omitted, FRAME defaults to the selected frame.\n\
1063If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
06537cc8 1064If MINIFRAME is a window, include only its own frame\n\
a9986780 1065and any frame now using that window as the minibuffer.\n\
f7af3f7b 1066If MINIFRAME is `visible', include all visible frames.\n\
06537cc8 1067If MINIFRAME is 0, include all visible and iconified frames.\n\
f7af3f7b 1068Otherwise, include all frames.")
ef2c57ac
RM
1069 (frame, miniframe)
1070 Lisp_Object frame, miniframe;
1071{
1072 Lisp_Object tail;
1073
1074 if (NILP (frame))
8d2666fe
GM
1075 frame = selected_frame;
1076 CHECK_LIVE_FRAME (frame, 0);
ef2c57ac
RM
1077 return prev_frame (frame, miniframe);
1078}
dc6f92b8 1079\f
808c0f20
RS
1080/* Return 1 if it is ok to delete frame F;
1081 0 if all frames aside from F are invisible.
1082 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 1083
d56b45eb 1084int
808c0f20
RS
1085other_visible_frames (f)
1086 FRAME_PTR f;
1087{
1088 /* We know the selected frame is visible,
1089 so if F is some other frame, it can't be the sole visible one. */
8d2666fe 1090 if (f == SELECTED_FRAME ())
c08c95c7
RS
1091 {
1092 Lisp_Object frames;
1093 int count = 0;
1094
1095 for (frames = Vframe_list;
1096 CONSP (frames);
1097 frames = XCONS (frames)->cdr)
1098 {
ab9f008d 1099 Lisp_Object this;
c08c95c7 1100
ab9f008d 1101 this = XCONS (frames)->car;
808c0f20
RS
1102 /* Verify that the frame's window still exists
1103 and we can still talk to it. And note any recent change
1104 in visibility. */
032d78fe
GV
1105#ifdef HAVE_WINDOW_SYSTEM
1106 if (FRAME_WINDOW_P (XFRAME (this)))
5e7b7c5b 1107 {
b0509a40 1108 x_sync (XFRAME (this));
5e7b7c5b
RS
1109 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1110 }
1111#endif
1112
c08c95c7
RS
1113 if (FRAME_VISIBLE_P (XFRAME (this))
1114 || FRAME_ICONIFIED_P (XFRAME (this))
1115 /* Allow deleting the terminal frame when at least
1116 one X frame exists! */
032d78fe 1117 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
c08c95c7
RS
1118 count++;
1119 }
808c0f20 1120 return count > 1;
c08c95c7 1121 }
808c0f20
RS
1122 return 1;
1123}
1124
1125DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1126 "Delete FRAME, permanently eliminating it from use.\n\
1127If omitted, FRAME defaults to the selected frame.\n\
1128A frame may not be deleted if its minibuffer is used by other frames.\n\
1129Normally, you may not delete a frame if all other frames are invisible,\n\
1130but if the second optional argument FORCE is non-nil, you may do so.")
1131 (frame, force)
1132 Lisp_Object frame, force;
1133{
1134 struct frame *f;
8d2666fe 1135 struct frame *sf = SELECTED_FRAME ();
99b92e64 1136 int minibuffer_selected;
808c0f20
RS
1137
1138 if (EQ (frame, Qnil))
1139 {
8d2666fe 1140 f = sf;
2d80a27a 1141 XSETFRAME (frame, f);
808c0f20
RS
1142 }
1143 else
1144 {
1145 CHECK_FRAME (frame, 0);
1146 f = XFRAME (frame);
1147 }
1148
1149 if (! FRAME_LIVE_P (f))
1150 return Qnil;
1151
1152 if (NILP (force) && !other_visible_frames (f))
1153 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 1154
00c5fd51
RS
1155#if 0
1156 /* This is a nice idea, but x_connection_closed needs to be able
1157 to delete the last frame, if it is gone. */
e9687ee8
RS
1158 if (NILP (XCONS (Vframe_list)->cdr))
1159 error ("Attempt to delete the only frame");
00c5fd51 1160#endif
e9687ee8 1161
ff11dfa1
JB
1162 /* Does this frame have a minibuffer, and is it the surrogate
1163 minibuffer for any other frame? */
fd0c2bd1 1164 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 1165 {
ff11dfa1 1166 Lisp_Object frames;
1113d9db 1167
ff11dfa1
JB
1168 for (frames = Vframe_list;
1169 CONSP (frames);
1170 frames = XCONS (frames)->cdr)
1113d9db 1171 {
7a8cc307
RS
1172 Lisp_Object this;
1173 this = XCONS (frames)->car;
1113d9db 1174
ff11dfa1
JB
1175 if (! EQ (this, frame)
1176 && EQ (frame,
7a8cc307
RS
1177 WINDOW_FRAME (XWINDOW
1178 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 1179 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 1180 }
dc6f92b8
JB
1181 }
1182
99b92e64
RS
1183 minibuffer_selected = EQ (minibuf_window, selected_window);
1184
ff11dfa1 1185 /* Don't let the frame remain selected. */
8d2666fe 1186 if (f == sf)
06537cc8
RS
1187 {
1188 Lisp_Object tail, frame1;
1189
1190 /* Look for another visible frame on the same terminal. */
1191 frame1 = next_frame (frame, Qvisible);
1192
1193 /* If there is none, find *some* other frame. */
1194 if (NILP (frame1) || EQ (frame1, frame))
1195 {
1196 FOR_EACH_FRAME (tail, frame1)
1197 {
1198 if (! EQ (frame, frame1))
1199 break;
1200 }
1201 }
1202
1203 do_switch_frame (frame1, Qnil, 0);
1204 }
dc6f92b8 1205
ff11dfa1
JB
1206 /* Don't allow minibuf_window to remain on a deleted frame. */
1207 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 1208 {
8d2666fe 1209 Fset_window_buffer (sf->minibuffer_window,
dc6f92b8 1210 XWINDOW (minibuf_window)->buffer);
8d2666fe 1211 minibuf_window = sf->minibuffer_window;
99b92e64
RS
1212
1213 /* If the dying minibuffer window was selected,
1214 select the new one. */
1215 if (minibuffer_selected)
1216 Fselect_window (minibuf_window);
dc6f92b8
JB
1217 }
1218
bb2a0a65
RS
1219 /* Clear any X selections for this frame. */
1220#ifdef HAVE_X_WINDOWS
1221 if (FRAME_X_P (f))
1222 x_clear_frame_selections (f);
1223#endif
1224
18082e2d
GM
1225 /* Free glyphs.
1226 This function must be called before the window tree of the
1227 frame is deleted because windows contain dynamically allocated
1228 memory. */
1229 free_glyphs (f);
1230
4a88b3b0
JB
1231 /* Mark all the windows that used to be on FRAME as deleted, and then
1232 remove the reference to them. */
1233 delete_all_subwindows (XWINDOW (f->root_window));
1234 f->root_window = Qnil;
1235
ff11dfa1 1236 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 1237 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 1238
60a8823e 1239 if (f->namebuf)
18082e2d 1240 xfree (f->namebuf);
d2bee99e 1241 if (FRAME_INSERT_COST (f))
18082e2d 1242 xfree (FRAME_INSERT_COST (f));
d2bee99e 1243 if (FRAME_DELETEN_COST (f))
18082e2d 1244 xfree (FRAME_DELETEN_COST (f));
d2bee99e 1245 if (FRAME_INSERTN_COST (f))
18082e2d 1246 xfree (FRAME_INSERTN_COST (f));
d2bee99e 1247 if (FRAME_DELETE_COST (f))
18082e2d 1248 xfree (FRAME_DELETE_COST (f));
25734faf 1249 if (FRAME_MESSAGE_BUF (f))
18082e2d 1250 xfree (FRAME_MESSAGE_BUF (f));
d2bee99e 1251
71025e5e
KH
1252#ifdef HAVE_WINDOW_SYSTEM
1253 /* Free all fontset data. */
1254 free_fontset_data (FRAME_FONTSET_DATA (f));
1255#endif
1256
8678b9cc
JB
1257 /* Since some events are handled at the interrupt level, we may get
1258 an event for f at any time; if we zero out the frame's display
1259 now, then we may trip up the event-handling code. Instead, we'll
1260 promise that the display of the frame must be valid until we have
1261 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
1262
1263 /* I think this should be done with a hook. */
032d78fe
GV
1264#ifdef HAVE_WINDOW_SYSTEM
1265 if (FRAME_WINDOW_P (f))
8678b9cc 1266 x_destroy_window (f);
d5e7c279
JB
1267#endif
1268
574a1a90
RS
1269/* Done by x_destroy_window above already */
1270#if 0
1271#ifdef macintosh
1272 if (FRAME_MAC_P (f))
1273 DisposeMacWindow (f->output_data.mac);
1274#endif
1275#endif
1276
7556890b 1277 f->output_data.nothing = 0;
8678b9cc 1278
ff11dfa1 1279 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 1280 another one. */
ff11dfa1 1281 if (f == last_nonminibuf_frame)
d5e7c279 1282 {
ff11dfa1 1283 Lisp_Object frames;
1113d9db 1284
ff11dfa1 1285 last_nonminibuf_frame = 0;
d5e7c279 1286
ff11dfa1
JB
1287 for (frames = Vframe_list;
1288 CONSP (frames);
1289 frames = XCONS (frames)->cdr)
d5e7c279 1290 {
ff11dfa1
JB
1291 f = XFRAME (XCONS (frames)->car);
1292 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1293 {
ff11dfa1 1294 last_nonminibuf_frame = f;
d5e7c279
JB
1295 break;
1296 }
1297 }
1298 }
dc6f92b8 1299
c4c6d073
KH
1300 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1301 find another one. Prefer minibuffer-only frames, but also notice
1302 frames with other windows. */
c60f3a6a 1303 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1113d9db 1304 {
ff11dfa1 1305 Lisp_Object frames;
1113d9db 1306
ff11dfa1 1307 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1308 Lisp_Object frame_with_minibuf;
32fda9ba
RS
1309 /* Some frame we found on the same kboard, or nil if there are none. */
1310 Lisp_Object frame_on_same_kboard;
1113d9db 1311
32fda9ba 1312 frame_on_same_kboard = Qnil;
ab9f008d 1313 frame_with_minibuf = Qnil;
32fda9ba 1314
ff11dfa1
JB
1315 for (frames = Vframe_list;
1316 CONSP (frames);
1317 frames = XCONS (frames)->cdr)
1113d9db 1318 {
ab9f008d 1319 Lisp_Object this;
c4c6d073 1320 struct frame *f1;
1113d9db 1321
ab9f008d 1322 this = XCONS (frames)->car;
e35d291d 1323 if (!FRAMEP (this))
1113d9db 1324 abort ();
c4c6d073 1325 f1 = XFRAME (this);
1113d9db 1326
c4c6d073
KH
1327 /* Consider only frames on the same kboard
1328 and only those with minibuffers. */
1329 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1330 && FRAME_HAS_MINIBUF_P (f1))
1113d9db 1331 {
ff11dfa1 1332 frame_with_minibuf = this;
c4c6d073 1333 if (FRAME_MINIBUF_ONLY_P (f1))
1113d9db
JB
1334 break;
1335 }
32fda9ba
RS
1336
1337 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1338 frame_on_same_kboard = this;
1113d9db
JB
1339 }
1340
32fda9ba
RS
1341 if (!NILP (frame_on_same_kboard))
1342 {
1343 /* We know that there must be some frame with a minibuffer out
1344 there. If this were not true, all of the frames present
1345 would have to be minibufferless, which implies that at some
1346 point their minibuffer frames must have been deleted, but
1347 that is prohibited at the top; you can't delete surrogate
1348 minibuffer frames. */
1349 if (NILP (frame_with_minibuf))
1350 abort ();
1113d9db 1351
32fda9ba
RS
1352 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1353 }
1354 else
1355 /* No frames left on this kboard--say no minibuffer either. */
1356 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1113d9db
JB
1357 }
1358
e681c92a
RS
1359 /* Cause frame titles to update--necessary if we now have just one frame. */
1360 update_mode_lines = 1;
1361
dc6f92b8
JB
1362 return Qnil;
1363}
1364\f
1365/* Return mouse position in character cell units. */
1366
f9898cc6 1367DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1368 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1369The position is given in character cells, where (0, 0) is the\n\
1370upper-left corner.\n\
f9898cc6 1371If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1372to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1373and nil for X and Y.")
1374 ()
dc6f92b8 1375{
ff11dfa1 1376 FRAME_PTR f;
dbc4e1c1 1377 Lisp_Object lispy_dummy;
fd2777e0 1378 enum scroll_bar_part party_dummy;
dbc4e1c1 1379 Lisp_Object x, y;
5384466a 1380 int col, row;
dbc4e1c1 1381 unsigned long long_dummy;
dc6f92b8 1382
8d2666fe 1383 f = SELECTED_FRAME ();
c5074d8c
RS
1384 x = y = Qnil;
1385
f443c170 1386#ifdef HAVE_MOUSE
c5074d8c 1387 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1388 if (mouse_position_hook)
66e827dc 1389 (*mouse_position_hook) (&f, -1,
dbc4e1c1
JB
1390 &lispy_dummy, &party_dummy,
1391 &x, &y,
1392 &long_dummy);
76db7eb4
KH
1393 if (! NILP (x))
1394 {
1395 col = XINT (x);
1396 row = XINT (y);
8126c3b4 1397 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
76db7eb4
KH
1398 XSETINT (x, col);
1399 XSETINT (y, row);
1400 }
f443c170 1401#endif
2d80a27a 1402 XSETFRAME (lispy_dummy, f);
c5074d8c 1403 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1404}
1405
152e6c70
RS
1406DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1407 Smouse_pixel_position, 0, 0, 0,
1408 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1409The position is given in pixel units, where (0, 0) is the\n\
1410upper-left corner.\n\
1411If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1412to read the mouse position, it returns the selected frame for FRAME\n\
1413and nil for X and Y.")
1414 ()
1415{
1416 FRAME_PTR f;
1417 Lisp_Object lispy_dummy;
1418 enum scroll_bar_part party_dummy;
1419 Lisp_Object x, y;
1420 int col, row;
1421 unsigned long long_dummy;
1422
8d2666fe 1423 f = SELECTED_FRAME ();
152e6c70
RS
1424 x = y = Qnil;
1425
0c5c1cf7 1426#ifdef HAVE_MOUSE
152e6c70
RS
1427 /* It's okay for the hook to refrain from storing anything. */
1428 if (mouse_position_hook)
66e827dc 1429 (*mouse_position_hook) (&f, -1,
152e6c70
RS
1430 &lispy_dummy, &party_dummy,
1431 &x, &y,
1432 &long_dummy);
0c5c1cf7 1433#endif
2d80a27a 1434 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1435 return Fcons (lispy_dummy, Fcons (x, y));
1436}
1437
dc6f92b8 1438DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1439 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
e84ffeec
RS
1440Coordinates are relative to the frame, not a window,\n\
1441so the coordinates of the top left character in the frame\n\
1442may be nonzero due to left-hand scroll bars or the menu bar.\n\
1443\n\
1444This function is a no-op for an X frame that is not visible.\n\
efb57f43
RS
1445If you have just created a frame, you must wait for it to become visible\n\
1446before calling this function on it, like this.\n\
1447 (while (not (frame-visible-p frame)) (sleep-for .5))")
ff11dfa1
JB
1448 (frame, x, y)
1449 Lisp_Object frame, x, y;
dc6f92b8 1450{
ff11dfa1 1451 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1452 CHECK_NUMBER (x, 2);
1453 CHECK_NUMBER (y, 1);
1454
dbc4e1c1 1455 /* I think this should be done with a hook. */
032d78fe
GV
1456#ifdef HAVE_WINDOW_SYSTEM
1457 if (FRAME_WINDOW_P (XFRAME (frame)))
dc6f92b8 1458 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1459 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1460#else
be625e00 1461#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1462 if (FRAME_MSDOS_P (XFRAME (frame)))
1463 {
1464 Fselect_frame (frame, Qnil);
1465 mouse_moveto (XINT (x), XINT (y));
1466 }
1467#endif
dc6f92b8
JB
1468#endif
1469
1470 return Qnil;
1471}
152e6c70
RS
1472
1473DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1474 Sset_mouse_pixel_position, 3, 3, 0,
1475 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
efb57f43
RS
1476Note, this is a no-op for an X frame that is not visible.\n\
1477If you have just created a frame, you must wait for it to become visible\n\
1478before calling this function on it, like this.\n\
1479 (while (not (frame-visible-p frame)) (sleep-for .5))")
152e6c70
RS
1480 (frame, x, y)
1481 Lisp_Object frame, x, y;
1482{
1483 CHECK_LIVE_FRAME (frame, 0);
1484 CHECK_NUMBER (x, 2);
1485 CHECK_NUMBER (y, 1);
1486
1487 /* I think this should be done with a hook. */
032d78fe
GV
1488#ifdef HAVE_WINDOW_SYSTEM
1489 if (FRAME_WINDOW_P (XFRAME (frame)))
152e6c70 1490 /* Warping the mouse will cause enternotify and focus events. */
d4d76014 1491 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
bb221971 1492#else
be625e00 1493#if defined (MSDOS) && defined (HAVE_MOUSE)
bb221971
RS
1494 if (FRAME_MSDOS_P (XFRAME (frame)))
1495 {
1496 Fselect_frame (frame, Qnil);
1497 mouse_moveto (XINT (x), XINT (y));
1498 }
1499#endif
152e6c70
RS
1500#endif
1501
1502 return Qnil;
1503}
dc6f92b8 1504\f
98ce1622
RS
1505static void make_frame_visible_1 P_ ((Lisp_Object));
1506
ff11dfa1 1507DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1508 0, 1, "",
ff11dfa1 1509 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1510If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1511 (frame)
1512 Lisp_Object frame;
dc6f92b8 1513{
1aa66088 1514 if (NILP (frame))
8d2666fe 1515 frame = selected_frame;
1aa66088 1516
ff11dfa1 1517 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1518
dbc4e1c1 1519 /* I think this should be done with a hook. */
032d78fe
GV
1520#ifdef HAVE_WINDOW_SYSTEM
1521 if (FRAME_WINDOW_P (XFRAME (frame)))
02ff9dd5
RS
1522 {
1523 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1524 x_make_frame_visible (XFRAME (frame));
1525 }
fd0c2bd1 1526#endif
dc6f92b8 1527
98ce1622
RS
1528 make_frame_visible_1 (XFRAME (frame)->root_window);
1529
565620a5
RS
1530 /* Make menu bar update for the Buffers and Frams menus. */
1531 windows_or_buffers_changed++;
1532
ff11dfa1 1533 return frame;
dc6f92b8
JB
1534}
1535
98ce1622
RS
1536/* Update the display_time slot of the buffers shown in WINDOW
1537 and all its descendents. */
1538
1539static void
1540make_frame_visible_1 (window)
1541 Lisp_Object window;
1542{
1543 struct window *w;
1544
1545 for (;!NILP (window); window = w->next)
1546 {
1547 w = XWINDOW (window);
1548
1549 if (!NILP (w->buffer))
1550 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1551
1552 if (!NILP (w->vchild))
1553 make_frame_visible_1 (w->vchild);
1554 if (!NILP (w->hchild))
1555 make_frame_visible_1 (w->hchild);
1556 }
1557}
1558
ff11dfa1 1559DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1560 0, 2, "",
8693ca83 1561 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1562If omitted, FRAME defaults to the currently selected frame.\n\
1563Normally you may not make FRAME invisible if all other frames are invisible,\n\
1564but if the second optional argument FORCE is non-nil, you may do so.")
1565 (frame, force)
1566 Lisp_Object frame, force;
dc6f92b8 1567{
1aa66088 1568 if (NILP (frame))
8d2666fe 1569 frame = selected_frame;
1aa66088 1570
ff11dfa1 1571 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1572
808c0f20
RS
1573 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1574 error ("Attempt to make invisible the sole visible or iconified frame");
1575
3d378fdf 1576#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1577 /* Don't let the frame remain selected. */
8d2666fe 1578 if (EQ (frame, selected_frame))
61f94483 1579 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
3d378fdf 1580#endif
9c394f17
RS
1581
1582 /* Don't allow minibuf_window to remain on a deleted frame. */
1583 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1584 {
8d2666fe
GM
1585 struct frame *sf = XFRAME (selected_frame);
1586 Fset_window_buffer (sf->minibuffer_window,
9c394f17 1587 XWINDOW (minibuf_window)->buffer);
8d2666fe 1588 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1589 }
1590
dbc4e1c1 1591 /* I think this should be done with a hook. */
032d78fe
GV
1592#ifdef HAVE_WINDOW_SYSTEM
1593 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1594 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1595#endif
dc6f92b8 1596
565620a5
RS
1597 /* Make menu bar update for the Buffers and Frams menus. */
1598 windows_or_buffers_changed++;
1599
dc6f92b8
JB
1600 return Qnil;
1601}
1602
ff11dfa1 1603DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1604 0, 1, "",
8693ca83
JB
1605 "Make the frame FRAME into an icon.\n\
1606If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1607 (frame)
1608 Lisp_Object frame;
dc6f92b8 1609{
1aa66088 1610 if (NILP (frame))
8d2666fe 1611 frame = selected_frame;
1aa66088 1612
ff11dfa1 1613 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1614
3d378fdf 1615#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17 1616 /* Don't let the frame remain selected. */
8d2666fe 1617 if (EQ (frame, selected_frame))
9c394f17 1618 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1619#endif
9c394f17
RS
1620
1621 /* Don't allow minibuf_window to remain on a deleted frame. */
1622 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1623 {
8d2666fe
GM
1624 struct frame *sf = XFRAME (selected_frame);
1625 Fset_window_buffer (sf->minibuffer_window,
9c394f17 1626 XWINDOW (minibuf_window)->buffer);
8d2666fe 1627 minibuf_window = sf->minibuffer_window;
9c394f17
RS
1628 }
1629
dbc4e1c1 1630 /* I think this should be done with a hook. */
032d78fe
GV
1631#ifdef HAVE_WINDOW_SYSTEM
1632 if (FRAME_WINDOW_P (XFRAME (frame)))
ff11dfa1 1633 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1634#endif
dc6f92b8 1635
565620a5
RS
1636 /* Make menu bar update for the Buffers and Frams menus. */
1637 windows_or_buffers_changed++;
1638
dc6f92b8
JB
1639 return Qnil;
1640}
1641
ff11dfa1 1642DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1643 1, 1, 0,
ff11dfa1
JB
1644 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1645A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1646a window system, it may not show at all.\n\
fd0c2bd1 1647Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1648 (frame)
1649 Lisp_Object frame;
dc6f92b8 1650{
ff11dfa1 1651 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1652
5c044f55
RS
1653 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1654
a42e9724 1655 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1656 return Qt;
a42e9724 1657 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1658 return Qicon;
dc6f92b8
JB
1659 return Qnil;
1660}
1661
ff11dfa1 1662DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1663 0, 0, 0,
ff11dfa1 1664 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1665 ()
1666{
ff11dfa1
JB
1667 Lisp_Object tail, frame;
1668 struct frame *f;
dc6f92b8
JB
1669 Lisp_Object value;
1670
1671 value = Qnil;
ff11dfa1 1672 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1673 {
ff11dfa1 1674 frame = XCONS (tail)->car;
e35d291d 1675 if (!FRAMEP (frame))
dc6f92b8 1676 continue;
ff11dfa1 1677 f = XFRAME (frame);
a42e9724 1678 if (FRAME_VISIBLE_P (f))
ff11dfa1 1679 value = Fcons (frame, value);
dc6f92b8
JB
1680 }
1681 return value;
1682}
d5e7c279
JB
1683
1684
e518d5e1 1685DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
dbc4e1c1
JB
1686 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1687If FRAME is invisible, make it visible.\n\
828ac693 1688If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1689If Emacs is displaying on an ordinary terminal or some other device which\n\
1690doesn't support multiple overlapping frames, this function does nothing.")
1691 (frame)
1692 Lisp_Object frame;
1693{
828ac693 1694 if (NILP (frame))
8d2666fe 1695 frame = selected_frame;
828ac693 1696
dbc4e1c1 1697 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1698
1699 /* Do like the documentation says. */
1700 Fmake_frame_visible (frame);
1701
dbc4e1c1
JB
1702 if (frame_raise_lower_hook)
1703 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1704
1705 return Qnil;
1706}
1707
b49f5578 1708/* Should we have a corresponding function called Flower_Power? */
e518d5e1 1709DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
dbc4e1c1 1710 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1711If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1712If Emacs is displaying on an ordinary terminal or some other device which\n\
1713doesn't support multiple overlapping frames, this function does nothing.")
1714 (frame)
1715 Lisp_Object frame;
1716{
828ac693 1717 if (NILP (frame))
8d2666fe 1718 frame = selected_frame;
828ac693 1719
dbc4e1c1
JB
1720 CHECK_LIVE_FRAME (frame, 0);
1721
1722 if (frame_raise_lower_hook)
1723 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1724
1725 return Qnil;
1726}
1727
d5e7c279 1728\f
ff11dfa1 1729DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1730 1, 2, 0,
ff11dfa1 1731 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1732In other words, switch-frame events caused by events in FRAME will\n\
1733request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1734FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1735\n\
a42e9724 1736If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1737cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1738\n\
a42e9724
JB
1739Focus redirection is useful for temporarily redirecting keystrokes to\n\
1740a surrogate minibuffer frame when a frame doesn't have its own\n\
1741minibuffer window.\n\
d5e7c279 1742\n\
a42e9724
JB
1743A frame's focus redirection can be changed by select-frame. If frame\n\
1744FOO is selected, and then a different frame BAR is selected, any\n\
1745frames redirecting their focus to FOO are shifted to redirect their\n\
1746focus to BAR. This allows focus redirection to work properly when the\n\
1747user switches from one frame to another using `select-window'.\n\
1748\n\
1749This means that a frame whose focus is redirected to itself is treated\n\
1750differently from a frame whose focus is redirected to nil; the former\n\
1751is affected by select-frame, while the latter is not.\n\
1752\n\
1753The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1754 (frame, focus_frame)
1755 Lisp_Object frame, focus_frame;
d5e7c279 1756{
13144095
JB
1757 /* Note that we don't check for a live frame here. It's reasonable
1758 to redirect the focus of a frame you're about to delete, if you
1759 know what other frame should receive those keystrokes. */
1760 CHECK_FRAME (frame, 0);
f9898cc6 1761
a42e9724 1762 if (! NILP (focus_frame))
ff11dfa1 1763 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1764
ff11dfa1 1765 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1766
ff11dfa1 1767 if (frame_rehighlight_hook)
dc0700f6 1768 (*frame_rehighlight_hook) (XFRAME (frame));
d5e7c279
JB
1769
1770 return Qnil;
1771}
1772
1773
ff11dfa1
JB
1774DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1775 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1776This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1777See `redirect-frame-focus'.")
1778 (frame)
1779 Lisp_Object frame;
d5e7c279 1780{
ff11dfa1 1781 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1782
ff11dfa1 1783 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1784}
1785
1786
dc6f92b8 1787\f
329ca574
RS
1788/* Return the value of frame parameter PROP in frame FRAME. */
1789
dc6f92b8 1790Lisp_Object
ff11dfa1
JB
1791get_frame_param (frame, prop)
1792 register struct frame *frame;
dc6f92b8
JB
1793 Lisp_Object prop;
1794{
1795 register Lisp_Object tem;
1796
ff11dfa1 1797 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1798 if (EQ (tem, Qnil))
1799 return tem;
1800 return Fcdr (tem);
1801}
1802
329ca574
RS
1803/* Return the buffer-predicate of the selected frame. */
1804
1805Lisp_Object
98ce1622
RS
1806frame_buffer_predicate (frame)
1807 Lisp_Object frame;
329ca574 1808{
98ce1622 1809 return XFRAME (frame)->buffer_predicate;
329ca574
RS
1810}
1811
fa54c6ae
RS
1812/* Return the buffer-list of the selected frame. */
1813
1814Lisp_Object
98ce1622
RS
1815frame_buffer_list (frame)
1816 Lisp_Object frame;
fa54c6ae 1817{
98ce1622 1818 return XFRAME (frame)->buffer_list;
fa54c6ae
RS
1819}
1820
1821/* Set the buffer-list of the selected frame. */
1822
1823void
98ce1622
RS
1824set_frame_buffer_list (frame, list)
1825 Lisp_Object frame, list;
fa54c6ae 1826{
98ce1622 1827 XFRAME (frame)->buffer_list = list;
fa54c6ae
RS
1828}
1829
1830/* Discard BUFFER from the buffer-list of each frame. */
1831
1832void
1833frames_discard_buffer (buffer)
1834 Lisp_Object buffer;
1835{
1836 Lisp_Object frame, tail;
1837
1838 FOR_EACH_FRAME (tail, frame)
1839 {
1840 XFRAME (frame)->buffer_list
1841 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1842 }
1843}
1844
214b3216
RS
1845/* Move BUFFER to the end of the buffer-list of each frame. */
1846
1847void
1848frames_bury_buffer (buffer)
1849 Lisp_Object buffer;
1850{
1851 Lisp_Object frame, tail;
1852
1853 FOR_EACH_FRAME (tail, frame)
1854 {
1855 XFRAME (frame)->buffer_list
1856 = nconc2 (Fdelq (buffer, XFRAME (frame)->buffer_list),
1857 Fcons (buffer, Qnil));
1858 }
1859}
1860
329ca574
RS
1861/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1862 If the alist already has an element for PROP, we change it. */
1863
dc6f92b8 1864void
fd0c2bd1 1865store_in_alist (alistptr, prop, val)
dc6f92b8 1866 Lisp_Object *alistptr, val;
fd0c2bd1 1867 Lisp_Object prop;
dc6f92b8
JB
1868{
1869 register Lisp_Object tem;
dc6f92b8 1870
dc6f92b8
JB
1871 tem = Fassq (prop, *alistptr);
1872 if (EQ (tem, Qnil))
1873 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1874 else
1875 Fsetcdr (tem, val);
1876}
1877
e5317d61
EZ
1878static int
1879frame_name_fnn_p (str, len)
1880 char *str;
1881 int len;
1882{
1883 if (len > 1 && str[0] == 'F')
1884 {
1885 char *end_ptr;
1886 long num = strtol (str + 1, &end_ptr, 10);
1887
1888 if (end_ptr == str + len)
1889 return 1;
1890 }
1891 return 0;
1892}
1893
1894/* Set the name of the terminal frame. Also used by MSDOS frames.
1895 Modeled after x_set_name which is used for WINDOW frames. */
1896
1897void
1898set_term_frame_name (f, name)
1899 struct frame *f;
1900 Lisp_Object name;
1901{
1902 f->explicit_name = ! NILP (name);
1903
1904 /* If NAME is nil, set the name to F<num>. */
1905 if (NILP (name))
1906 {
1907 char namebuf[20];
1908
1909 /* Check for no change needed in this very common case
1910 before we do any consing. */
e34c5c7d 1911 if (frame_name_fnn_p (XSTRING (f->name)->data,
fc932ac6 1912 STRING_BYTES (XSTRING (f->name))))
e5317d61
EZ
1913 return;
1914
1915 terminal_frame_count++;
1916 sprintf (namebuf, "F%d", terminal_frame_count);
1917 name = build_string (namebuf);
1918 }
1919 else
1920 {
1921 CHECK_STRING (name, 0);
1922
1923 /* Don't change the name if it's already NAME. */
1924 if (! NILP (Fstring_equal (name, f->name)))
1925 return;
1926
1927 /* Don't allow the user to set the frame name to F<num>, so it
1928 doesn't clash with the names we generate for terminal frames. */
fc932ac6 1929 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
e5317d61
EZ
1930 error ("Frame names of the form F<num> are usurped by Emacs");
1931 }
1932
1933 f->name = name;
1934 update_mode_lines = 1;
1935}
1936
dc6f92b8 1937void
ff11dfa1
JB
1938store_frame_param (f, prop, val)
1939 struct frame *f;
dc6f92b8
JB
1940 Lisp_Object prop, val;
1941{
1942 register Lisp_Object tem;
1943
fa54c6ae
RS
1944 if (EQ (prop, Qbuffer_list))
1945 {
1946 f->buffer_list = val;
1947 return;
1948 }
1949
ff11dfa1 1950 tem = Fassq (prop, f->param_alist);
dc6f92b8 1951 if (EQ (tem, Qnil))
ff11dfa1 1952 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1953 else
1954 Fsetcdr (tem, val);
bc93c097 1955
329ca574
RS
1956 if (EQ (prop, Qbuffer_predicate))
1957 f->buffer_predicate = val;
1958
032d78fe 1959 if (! FRAME_WINDOW_P (f))
e5317d61
EZ
1960 {
1961 if (EQ (prop, Qmenu_bar_lines))
1962 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1963 else if (EQ (prop, Qname))
1964 set_term_frame_name (f, val);
1965 }
a249de79 1966
e35d291d 1967 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1968 {
1969 if (! MINI_WINDOW_P (XWINDOW (val)))
1970 error ("Surrogate minibuffer windows must be minibuffer windows.");
1971
7af7ef38
KH
1972 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)
1973 && !EQ (val, f->minibuffer_window))
1974 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1975
1976 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1977 f->minibuffer_window = val;
bc93c097 1978 }
dc6f92b8
JB
1979}
1980
ff11dfa1
JB
1981DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1982 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1983It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1984The meaningful PARMs depend on the kind of frame.\n\
1985If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1986 (frame)
1987 Lisp_Object frame;
dc6f92b8
JB
1988{
1989 Lisp_Object alist;
f769f1b2 1990 FRAME_PTR f;
dd10ec4f 1991 int height, width;
dc6f92b8 1992
ff11dfa1 1993 if (EQ (frame, Qnil))
8d2666fe
GM
1994 frame = selected_frame;
1995
1996 CHECK_FRAME (frame, 0);
1997 f = XFRAME (frame);
dc6f92b8 1998
f769f1b2 1999 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
2000 return Qnil;
2001
ff11dfa1 2002 alist = Fcopy_alist (f->param_alist);
bb221971
RS
2003#ifdef MSDOS
2004 if (FRAME_MSDOS_P (f))
2005 {
4aec4b29
EZ
2006 int fg = FRAME_FOREGROUND_PIXEL (f);
2007 int bg = FRAME_BACKGROUND_PIXEL (f);
87f1940e
EZ
2008 Lisp_Object qreverse = intern ("reverse");
2009 int rv =
2010 !NILP (Fassq (qreverse, alist))
2011 || !NILP (Fassq (qreverse, Vdefault_frame_alist));
4aec4b29 2012
bb221971 2013 store_in_alist (&alist, intern ("foreground-color"),
87f1940e 2014 build_string (msdos_stdcolor_name (rv ? bg : fg)));
bb221971 2015 store_in_alist (&alist, intern ("background-color"),
87f1940e 2016 build_string (msdos_stdcolor_name (rv ? fg : bg)));
bb221971 2017 }
4aec4b29 2018 store_in_alist (&alist, intern ("font"), build_string ("ms-dos"));
bb221971 2019#endif
fd0c2bd1 2020 store_in_alist (&alist, Qname, f->name);
dd10ec4f
RS
2021 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2022 store_in_alist (&alist, Qheight, make_number (height));
2023 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2024 store_in_alist (&alist, Qwidth, make_number (width));
f769f1b2 2025 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 2026 store_in_alist (&alist, Qminibuffer,
39acc701 2027 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
2028 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2029 : FRAME_MINIBUF_WINDOW (f)));
2030 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
98ce1622 2031 store_in_alist (&alist, Qbuffer_list,
8d2666fe 2032 frame_buffer_list (selected_frame));
fd0c2bd1 2033
dbc4e1c1 2034 /* I think this should be done with a hook. */
032d78fe
GV
2035#ifdef HAVE_WINDOW_SYSTEM
2036 if (FRAME_WINDOW_P (f))
ff11dfa1 2037 x_report_frame_params (f, &alist);
b6dd20ed 2038 else
fd0c2bd1 2039#endif
16a3738c
KH
2040 {
2041 /* This ought to be correct in f->param_alist for an X frame. */
2042 Lisp_Object lines;
f4e93c40 2043 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
2044 store_in_alist (&alist, Qmenu_bar_lines, lines);
2045 }
dc6f92b8
JB
2046 return alist;
2047}
2048
ff11dfa1
JB
2049DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2050 Smodify_frame_parameters, 2, 2, 0,
2051 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
2052ALIST is an alist of parameters to change and their new values.\n\
2053Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
e80f3932
RS
2054The meaningful PARMs depend on the kind of frame.\n\
2055Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2056so that `frame-parameters' will return them.")
ff11dfa1
JB
2057 (frame, alist)
2058 Lisp_Object frame, alist;
dc6f92b8 2059{
fd0c2bd1 2060 FRAME_PTR f;
dc6f92b8
JB
2061 register Lisp_Object tail, elt, prop, val;
2062
ff11dfa1 2063 if (EQ (frame, Qnil))
8d2666fe
GM
2064 frame = selected_frame;
2065 CHECK_LIVE_FRAME (frame, 0);
2066 f = XFRAME (frame);
dc6f92b8 2067
dbc4e1c1 2068 /* I think this should be done with a hook. */
032d78fe
GV
2069#ifdef HAVE_WINDOW_SYSTEM
2070 if (FRAME_WINDOW_P (f))
fd0c2bd1 2071 x_set_frame_parameters (f, alist);
329ca574 2072 else
bb221971
RS
2073#endif
2074#ifdef MSDOS
2075 if (FRAME_MSDOS_P (f))
2076 IT_set_frame_parameters (f, alist);
2077 else
329ca574 2078#endif
574a1a90
RS
2079#ifdef macintosh
2080 if (FRAME_MAC_P (f))
2081 mac_set_frame_parameters (f, alist);
2082 else
2083#endif
2084
41d44f1f
RS
2085 {
2086 int length = XINT (Flength (alist));
2087 int i;
2088 Lisp_Object *parms
2089 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2090 Lisp_Object *values
2091 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2092
2093 /* Extract parm names and values into those vectors. */
2094
2095 i = 0;
2096 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2097 {
2098 Lisp_Object elt, prop, val;
2099
2100 elt = Fcar (tail);
2101 parms[i] = Fcar (elt);
2102 values[i] = Fcdr (elt);
2103 i++;
2104 }
2105
2106 /* Now process them in reverse of specified order. */
2107 for (i--; i >= 0; i--)
2108 {
2109 prop = parms[i];
2110 val = values[i];
2111 store_frame_param (f, prop, val);
2112 }
2113 }
dc6f92b8
JB
2114
2115 return Qnil;
2116}
2117\f
a26a1f95
RS
2118DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2119 0, 1, 0,
2120 "Height in pixels of a line in the font in frame FRAME.\n\
2121If FRAME is omitted, the selected frame is used.\n\
2122For a terminal frame, the value is always 1.")
ff11dfa1
JB
2123 (frame)
2124 Lisp_Object frame;
dc6f92b8 2125{
a26a1f95 2126 struct frame *f;
dc6f92b8 2127
a26a1f95 2128 if (NILP (frame))
8d2666fe
GM
2129 frame = selected_frame;
2130 CHECK_FRAME (frame, 0);
2131 f = XFRAME (frame);
a26a1f95 2132
032d78fe
GV
2133#ifdef HAVE_WINDOW_SYSTEM
2134 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2135 return make_number (x_char_height (f));
2136 else
dc6d9681 2137#endif
a26a1f95
RS
2138 return make_number (1);
2139}
dc6d9681 2140
dc6f92b8 2141
a26a1f95
RS
2142DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2143 0, 1, 0,
2144 "Width in pixels of characters in the font in frame FRAME.\n\
2145If FRAME is omitted, the selected frame is used.\n\
2146The width is the same for all characters, because\n\
2147currently Emacs supports only fixed-width fonts.\n\
2148For a terminal screen, the value is always 1.")
2149 (frame)
2150 Lisp_Object frame;
dc6f92b8 2151{
a26a1f95
RS
2152 struct frame *f;
2153
2154 if (NILP (frame))
8d2666fe
GM
2155 frame = selected_frame;
2156 CHECK_FRAME (frame, 0);
2157 f = XFRAME (frame);
a26a1f95 2158
032d78fe
GV
2159#ifdef HAVE_WINDOW_SYSTEM
2160 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2161 return make_number (x_char_width (f));
2162 else
2163#endif
2164 return make_number (1);
dc6f92b8
JB
2165}
2166
a26a1f95
RS
2167DEFUN ("frame-pixel-height", Fframe_pixel_height,
2168 Sframe_pixel_height, 0, 1, 0,
164a14ef 2169 "Return a FRAME's height in pixels.\n\
07822795
RS
2170This counts only the height available for text lines,\n\
2171not menu bars on window-system Emacs frames.\n\
164a14ef 2172For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
2173If FRAME is omitted, the selected frame is used.")
2174 (frame)
2175 Lisp_Object frame;
dc6f92b8 2176{
a26a1f95
RS
2177 struct frame *f;
2178
2179 if (NILP (frame))
8d2666fe
GM
2180 frame = selected_frame;
2181 CHECK_FRAME (frame, 0);
2182 f = XFRAME (frame);
a26a1f95 2183
032d78fe
GV
2184#ifdef HAVE_WINDOW_SYSTEM
2185 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2186 return make_number (x_pixel_height (f));
2187 else
dc6d9681 2188#endif
a26a1f95
RS
2189 return make_number (FRAME_HEIGHT (f));
2190}
2191
2192DEFUN ("frame-pixel-width", Fframe_pixel_width,
2193 Sframe_pixel_width, 0, 1, 0,
2194 "Return FRAME's width in pixels.\n\
164a14ef 2195For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
2196If FRAME is omitted, the selected frame is used.")
2197 (frame)
2198 Lisp_Object frame;
2199{
2200 struct frame *f;
2201
2202 if (NILP (frame))
8d2666fe
GM
2203 frame = selected_frame;
2204 CHECK_FRAME (frame, 0);
2205 f = XFRAME (frame);
dc6f92b8 2206
032d78fe
GV
2207#ifdef HAVE_WINDOW_SYSTEM
2208 if (FRAME_WINDOW_P (f))
a26a1f95
RS
2209 return make_number (x_pixel_width (f));
2210 else
2211#endif
2212 return make_number (FRAME_WIDTH (f));
2213}
2214\f
ff11dfa1
JB
2215DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2216 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 2217Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1 2218but that the idea of the actual height of the frame should not be changed.")
735eeca3
EN
2219 (frame, lines, pretend)
2220 Lisp_Object frame, lines, pretend;
dc6f92b8 2221{
ff11dfa1 2222 register struct frame *f;
dc6f92b8 2223
735eeca3 2224 CHECK_NUMBER (lines, 0);
ff11dfa1 2225 if (NILP (frame))
8d2666fe
GM
2226 frame = selected_frame;
2227 CHECK_LIVE_FRAME (frame, 0);
2228 f = XFRAME (frame);
dc6f92b8 2229
dbc4e1c1 2230 /* I think this should be done with a hook. */
032d78fe
GV
2231#ifdef HAVE_WINDOW_SYSTEM
2232 if (FRAME_WINDOW_P (f))
dc6f92b8 2233 {
735eeca3
EN
2234 if (XINT (lines) != f->height)
2235 x_set_window_size (f, 1, f->width, XINT (lines));
32347cf4 2236 do_pending_window_change (0);
dc6f92b8
JB
2237 }
2238 else
fd0c2bd1 2239#endif
32347cf4 2240 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
dc6f92b8
JB
2241 return Qnil;
2242}
2243
ff11dfa1
JB
2244DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2245 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 2246Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
2247but that the idea of the actual width of the frame should not be changed.")
2248 (frame, cols, pretend)
fd0c2bd1 2249 Lisp_Object frame, cols, pretend;
dc6f92b8 2250{
ff11dfa1 2251 register struct frame *f;
dc6f92b8 2252 CHECK_NUMBER (cols, 0);
ff11dfa1 2253 if (NILP (frame))
8d2666fe
GM
2254 frame = selected_frame;
2255 CHECK_LIVE_FRAME (frame, 0);
2256 f = XFRAME (frame);
dc6f92b8 2257
dbc4e1c1 2258 /* I think this should be done with a hook. */
032d78fe
GV
2259#ifdef HAVE_WINDOW_SYSTEM
2260 if (FRAME_WINDOW_P (f))
dc6f92b8 2261 {
ff11dfa1 2262 if (XINT (cols) != f->width)
808c0f20 2263 x_set_window_size (f, 1, XINT (cols), f->height);
32347cf4 2264 do_pending_window_change (0);
dc6f92b8
JB
2265 }
2266 else
fd0c2bd1 2267#endif
32347cf4 2268 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
dc6f92b8
JB
2269 return Qnil;
2270}
2271
ff11dfa1
JB
2272DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2273 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2274 (frame, cols, rows)
2275 Lisp_Object frame, cols, rows;
dc6f92b8 2276{
ff11dfa1 2277 register struct frame *f;
dc6f92b8
JB
2278 int mask;
2279
ff11dfa1 2280 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2281 CHECK_NUMBER (cols, 2);
2282 CHECK_NUMBER (rows, 1);
ff11dfa1 2283 f = XFRAME (frame);
dc6f92b8 2284
dbc4e1c1 2285 /* I think this should be done with a hook. */
032d78fe
GV
2286#ifdef HAVE_WINDOW_SYSTEM
2287 if (FRAME_WINDOW_P (f))
dc6f92b8 2288 {
29824ce2
RS
2289 if (XINT (rows) != f->height || XINT (cols) != f->width
2290 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
808c0f20 2291 x_set_window_size (f, 1, XINT (cols), XINT (rows));
32347cf4 2292 do_pending_window_change (0);
dc6f92b8
JB
2293 }
2294 else
fd0c2bd1 2295#endif
32347cf4 2296 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
dc6f92b8
JB
2297
2298 return Qnil;
2299}
2300
ff11dfa1
JB
2301DEFUN ("set-frame-position", Fset_frame_position,
2302 Sset_frame_position, 3, 3, 0,
2303 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
2304This is actually the position of the upper left corner of the frame.\n\
2305Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 2306the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
2307 (frame, xoffset, yoffset)
2308 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 2309{
ff11dfa1 2310 register struct frame *f;
dc6f92b8
JB
2311 int mask;
2312
ff11dfa1 2313 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
2314 CHECK_NUMBER (xoffset, 1);
2315 CHECK_NUMBER (yoffset, 2);
ff11dfa1 2316 f = XFRAME (frame);
dc6f92b8 2317
dbc4e1c1 2318 /* I think this should be done with a hook. */
032d78fe
GV
2319#ifdef HAVE_WINDOW_SYSTEM
2320 if (FRAME_WINDOW_P (f))
c7c70761 2321 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 2322#endif
dc6f92b8
JB
2323
2324 return Qt;
2325}
dc6d9681 2326
dc6f92b8 2327\f
dfcf069d 2328void
ff11dfa1 2329syms_of_frame ()
dc6f92b8 2330{
a249de79 2331 syms_of_frame_1 ();
dc6f92b8 2332
ff11dfa1 2333 staticpro (&Vframe_list);
dc6f92b8 2334
ff11dfa1
JB
2335 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2336 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
2337
2338 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 2339 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
2340 Vemacs_iconified = Qnil;
2341
c60f3a6a 2342 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
ff11dfa1 2343 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 2344\n\
ff11dfa1 2345Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
2346appropriate surrogate.\n\
2347\n\
2348Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 2349frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
2350minibuffer, no matter what this variable is set to. This means that\n\
2351this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 2352current set of frames, or where the minibuffer is currently being\n\
f9898cc6 2353displayed.");
dc6f92b8 2354
5add3885 2355 defsubr (&Sactive_minibuffer_window);
ff11dfa1 2356 defsubr (&Sframep);
dbc4e1c1 2357 defsubr (&Sframe_live_p);
bb1513c9 2358 defsubr (&Smake_terminal_frame);
0f85737c 2359 defsubr (&Shandle_switch_frame);
1c212787 2360 defsubr (&Signore_event);
ff11dfa1
JB
2361 defsubr (&Sselect_frame);
2362 defsubr (&Sselected_frame);
2363 defsubr (&Swindow_frame);
2364 defsubr (&Sframe_root_window);
d446a856 2365 defsubr (&Sframe_first_window);
ff11dfa1 2366 defsubr (&Sframe_selected_window);
4a7cfafc 2367 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
2368 defsubr (&Sframe_list);
2369 defsubr (&Snext_frame);
ef2c57ac 2370 defsubr (&Sprevious_frame);
ff11dfa1 2371 defsubr (&Sdelete_frame);
f9898cc6 2372 defsubr (&Smouse_position);
152e6c70 2373 defsubr (&Smouse_pixel_position);
dc6f92b8 2374 defsubr (&Sset_mouse_position);
152e6c70 2375 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 2376#if 0
ff11dfa1
JB
2377 defsubr (&Sframe_configuration);
2378 defsubr (&Srestore_frame_configuration);
dc6f92b8 2379#endif
ff11dfa1
JB
2380 defsubr (&Smake_frame_visible);
2381 defsubr (&Smake_frame_invisible);
2382 defsubr (&Siconify_frame);
2383 defsubr (&Sframe_visible_p);
2384 defsubr (&Svisible_frame_list);
b49f5578
JB
2385 defsubr (&Sraise_frame);
2386 defsubr (&Slower_frame);
ff11dfa1
JB
2387 defsubr (&Sredirect_frame_focus);
2388 defsubr (&Sframe_focus);
2389 defsubr (&Sframe_parameters);
2390 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
2391 defsubr (&Sframe_char_height);
2392 defsubr (&Sframe_char_width);
2393 defsubr (&Sframe_pixel_height);
2394 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
2395 defsubr (&Sset_frame_height);
2396 defsubr (&Sset_frame_width);
2397 defsubr (&Sset_frame_size);
2398 defsubr (&Sset_frame_position);
dc6f92b8 2399}
e5d77022 2400
dfcf069d 2401void
2f0b07e0
JB
2402keys_of_frame ()
2403{
0f85737c 2404 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 2405 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
1c212787
KH
2406 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2407 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");
2f0b07e0 2408}