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