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