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