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