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