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