(tags-loop-scan): Set default value to an error form.
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
7c299e7a 2 Copyright (C) 1989, 1992, 1993 Free Software Foundation.
dc6f92b8
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
1113d9db 8the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
d5e7c279
JB
20#include <stdio.h>
21
dc6f92b8 22#include "config.h"
cc38027b
JB
23#include "lisp.h"
24#include "frame.h"
e5d77022 25
ff11dfa1 26#ifdef MULTI_FRAME
e5d77022 27
bff19c8d 28#include "buffer.h"
dc6f92b8 29#include "window.h"
d5e7c279 30#include "termhooks.h"
dc6f92b8 31
2f0b07e0
JB
32/* These help us bind and responding to switch-frame events. */
33#include "commands.h"
34#include "keyboard.h"
35
dc6f92b8 36Lisp_Object Vemacs_iconified;
ff11dfa1
JB
37Lisp_Object Vframe_list;
38Lisp_Object Vterminal_frame;
39Lisp_Object Vdefault_minibuffer_frame;
40Lisp_Object Vdefault_frame_alist;
fd0c2bd1
JB
41
42/* Evaluate this expression to rebuild the section of syms_of_frame
43 that initializes and staticpros the symbols declared below. Note
44 that Emacs 18 has a bug that keeps C-x C-e from being able to
45 evaluate this expression.
46
47(progn
48 ;; Accumulate a list of the symbols we want to initialize from the
49 ;; declarations at the top of the file.
50 (goto-char (point-min))
51 (search-forward "/\*&&& symbols declared here &&&*\/\n")
52 (let (symbol-list)
53 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
54 (setq symbol-list
55 (cons (buffer-substring (match-beginning 1) (match-end 1))
56 symbol-list))
57 (forward-line 1))
58 (setq symbol-list (nreverse symbol-list))
59 ;; Delete the section of syms_of_... where we initialize the symbols.
60 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
61 (let ((start (point)))
62 (while (looking-at "^ Q")
63 (forward-line 2))
64 (kill-region start (point)))
65 ;; Write a new symbol initialization section.
66 (while symbol-list
67 (insert (format " %s = intern (\"" (car symbol-list)))
68 (let ((start (point)))
69 (insert (substring (car symbol-list) 1))
70 (subst-char-in-region start (point) ?_ ?-))
71 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
72 (setq symbol-list (cdr symbol-list)))))
73 */
74
75/*&&& symbols declared here &&&*/
76Lisp_Object Qframep;
77Lisp_Object Qlive_frame_p;
78Lisp_Object Qheight;
79Lisp_Object Qicon;
bc93c097 80Lisp_Object Qminibuffer;
fd0c2bd1
JB
81Lisp_Object Qmodeline;
82Lisp_Object Qname;
83Lisp_Object Qnone;
84Lisp_Object Qonly;
85Lisp_Object Qunsplittable;
86Lisp_Object Qwidth;
87Lisp_Object Qx;
dc6f92b8
JB
88
89extern Lisp_Object Vminibuffer_list;
90extern Lisp_Object get_minibuffer ();
91\f
ff11dfa1
JB
92DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
93 "Return non-nil if OBJECT is a frame.\n\
94Value is t for a termcap frame (a character-only terminal),\n\
95`x' for an Emacs frame that is really an X window.\n\
96Also see `live-frame-p'.")
f9898cc6
JB
97 (object)
98 Lisp_Object object;
dc6f92b8 99{
ff11dfa1 100 if (XTYPE (object) != Lisp_Frame)
dc6f92b8 101 return Qnil;
ff11dfa1 102 switch (XFRAME (object)->output_method)
dc6f92b8
JB
103 {
104 case output_termcap:
105 return Qt;
106 case output_x_window:
fd0c2bd1 107 return Qx;
dc6f92b8
JB
108 default:
109 abort ();
110 }
111}
112
ff11dfa1
JB
113DEFUN ("live-frame-p", Flive_frame_p, Slive_frame_p, 1, 1, 0,
114 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
115Value is nil if OBJECT is not a live frame. If object is a live\n\
116frame, the return value indicates what sort of output device it is\n\
117displayed on. Value is t for a termcap frame (a character-only\n\
118terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
119 (object)
120 Lisp_Object object;
121{
ff11dfa1
JB
122 return ((FRAMEP (object)
123 && FRAME_LIVE_P (XFRAME (object)))
124 ? Fframep (object)
f9898cc6
JB
125 : Qnil);
126}
127
ff11dfa1
JB
128struct frame *
129make_frame (mini_p)
dc6f92b8
JB
130 int mini_p;
131{
ff11dfa1
JB
132 Lisp_Object frame;
133 register struct frame *f;
dc6f92b8
JB
134 register Lisp_Object root_window;
135 register Lisp_Object mini_window;
136
ff11dfa1 137 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
d5e7c279
JB
138 - sizeof (Lisp_Object)))
139 / sizeof (Lisp_Object)),
dc6f92b8 140 make_number (0));
ff11dfa1
JB
141 XSETTYPE (frame, Lisp_Frame);
142 f = XFRAME (frame);
143
144 f->cursor_x = 0;
145 f->cursor_y = 0;
146 f->current_glyphs = 0;
147 f->desired_glyphs = 0;
148 f->visible = 0;
323405de 149 f->async_visible = 0;
ff11dfa1
JB
150 f->display.nothing = 0;
151 f->iconified = 0;
323405de 152 f->async_iconified = 0;
ff11dfa1
JB
153 f->wants_modeline = 1;
154 f->auto_raise = 0;
155 f->auto_lower = 0;
156 f->no_split = 0;
157 f->garbaged = 0;
158 f->has_minibuffer = mini_p;
a42e9724 159 f->focus_frame = Qnil;
804518aa 160 f->explicit_name = 0;
a42e9724
JB
161 f->can_have_scrollbars = 0;
162 f->has_vertical_scrollbars = 0;
ff11dfa1 163 f->param_alist = Qnil;
7c299e7a
JB
164 f->scrollbars = Qnil;
165 f->condemned_scrollbars = Qnil;
dc6f92b8 166
cc38027b 167 root_window = make_window ();
dc6f92b8
JB
168 if (mini_p)
169 {
cc38027b 170 mini_window = make_window ();
dc6f92b8
JB
171 XWINDOW (root_window)->next = mini_window;
172 XWINDOW (mini_window)->prev = root_window;
173 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
174 XWINDOW (mini_window)->frame = frame;
175 f->minibuffer_window = mini_window;
dc6f92b8
JB
176 }
177 else
178 {
179 mini_window = Qnil;
180 XWINDOW (root_window)->next = Qnil;
ff11dfa1 181 f->minibuffer_window = Qnil;
dc6f92b8
JB
182 }
183
ff11dfa1 184 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
185
186 /* 10 is arbitrary,
187 just so that there is "something there."
ff11dfa1 188 Correct size will be set up later with change_frame_size. */
dc6f92b8 189
ff11dfa1
JB
190 f->width = 10;
191 f->height = 10;
dc6f92b8
JB
192
193 XFASTINT (XWINDOW (root_window)->width) = 10;
194 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
195
196 if (mini_p)
197 {
198 XFASTINT (XWINDOW (mini_window)->width) = 10;
199 XFASTINT (XWINDOW (mini_window)->top) = 9;
200 XFASTINT (XWINDOW (mini_window)->height) = 1;
201 }
202
ff11dfa1 203 /* Choose a buffer for the frame's root window. */
5bce042c
JB
204 {
205 Lisp_Object buf;
206
207 XWINDOW (root_window)->buffer = Qt;
208 buf = Fcurrent_buffer ();
209 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
210 a space), try to find another one. */
211 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 212 buf = Fother_buffer (buf, Qnil);
5bce042c
JB
213 Fset_window_buffer (root_window, buf);
214 }
215
dc6f92b8
JB
216 if (mini_p)
217 {
218 XWINDOW (mini_window)->buffer = Qt;
219 Fset_window_buffer (mini_window,
265a9e55 220 (NILP (Vminibuffer_list)
dc6f92b8
JB
221 ? get_minibuffer (0)
222 : Fcar (Vminibuffer_list)));
223 }
224
ff11dfa1
JB
225 f->root_window = root_window;
226 f->selected_window = root_window;
d5e7c279
JB
227 /* Make sure this window seems more recently used than
228 a newly-created, never-selected window. */
ff11dfa1 229 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
dc6f92b8 230
ff11dfa1 231 Vframe_list = Fcons (frame, Vframe_list);
dc6f92b8 232
ff11dfa1 233 return f;
dc6f92b8
JB
234}
235\f
ff11dfa1 236/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
237 MINI_WINDOW is the minibuffer window to use. nil means use the
238 default (the global minibuffer). */
239
ff11dfa1
JB
240struct frame *
241make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
242 register Lisp_Object mini_window;
243{
ff11dfa1 244 register struct frame *f;
dc6f92b8
JB
245
246 /* Choose the minibuffer window to use. */
265a9e55 247 if (NILP (mini_window))
dc6f92b8 248 {
ff11dfa1
JB
249 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
250 error ("default-minibuffer-frame must be set when creating minibufferless frames");
251 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
252 error ("default-minibuffer-frame must be a live frame");
253 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
254 }
255 else
256 {
774910eb 257 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8
JB
258 }
259
ff11dfa1
JB
260 /* Make a frame containing just a root window. */
261 f = make_frame (0);
dc6f92b8
JB
262
263 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 264 f->minibuffer_window = mini_window;
dc6f92b8 265 Fset_window_buffer (mini_window,
265a9e55 266 (NILP (Vminibuffer_list)
dc6f92b8
JB
267 ? get_minibuffer (0)
268 : Fcar (Vminibuffer_list)));
ff11dfa1 269 return f;
dc6f92b8
JB
270}
271
ff11dfa1 272/* Make a frame containing only a minibuffer window. */
dc6f92b8 273
ff11dfa1
JB
274struct frame *
275make_minibuffer_frame ()
dc6f92b8 276{
ff11dfa1 277 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 278
ff11dfa1 279 register struct frame *f = make_frame (0);
dc6f92b8 280 register Lisp_Object mini_window;
ff11dfa1 281 register Lisp_Object frame;
dc6f92b8 282
ff11dfa1 283 XSET (frame, Lisp_Frame, f);
dc6f92b8 284
804518aa 285 f->auto_raise = 0;
ff11dfa1
JB
286 f->auto_lower = 0;
287 f->no_split = 1;
288 f->wants_modeline = 0;
289 f->has_minibuffer = 1;
dc6f92b8
JB
290
291 /* Now label the root window as also being the minibuffer.
292 Avoid infinite looping on the window chain by marking next pointer
293 as nil. */
294
ff11dfa1 295 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
296 XWINDOW (mini_window)->mini_p = Qt;
297 XWINDOW (mini_window)->next = Qnil;
804518aa 298 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 299 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
300
301 /* Put the proper buffer in that window. */
302
303 Fset_window_buffer (mini_window,
265a9e55 304 (NILP (Vminibuffer_list)
dc6f92b8
JB
305 ? get_minibuffer (0)
306 : Fcar (Vminibuffer_list)));
ff11dfa1 307 return f;
dc6f92b8
JB
308}
309\f
ff11dfa1 310/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 311
ff11dfa1
JB
312struct frame *
313make_terminal_frame ()
dc6f92b8 314{
ff11dfa1
JB
315 register struct frame *f;
316
317 Vframe_list = Qnil;
318 f = make_frame (1);
319 f->name = build_string ("terminal");
a42e9724 320 FRAME_SET_VISIBLE (f, 1);
ff11dfa1
JB
321 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
322 XSET (Vterminal_frame, Lisp_Frame, f);
323 return f;
dc6f92b8
JB
324}
325\f
2f0b07e0 326DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
8693ca83 327 "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
d5e7c279 328selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
2f0b07e0
JB
329focus on that frame.\n\
330\n\
331This function is interactive, and may be bound to the ``switch-frame''\n\
332event; when invoked this way, it switches to the frame named in the\n\
333event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
a42e9724
JB
334if it is, select the frame named in the event.\n\
335\n\
336Changing the selected frame can change focus redirections. See\n\
337`redirect-frame-focus' for details.")
ff11dfa1
JB
338 (frame, no_enter)
339 Lisp_Object frame, no_enter;
dc6f92b8 340{
2f0b07e0
JB
341 /* If FRAME is a switch-frame event, extract the frame we should
342 switch to. */
343 if (CONSP (frame)
344 && EQ (XCONS (frame)->car, Qswitch_frame)
345 && CONSP (XCONS (frame)->cdr))
346 frame = XCONS (XCONS (frame)->cdr)->car;
347
ff11dfa1 348 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 349
ff11dfa1
JB
350 if (selected_frame == XFRAME (frame))
351 return frame;
dc6f92b8 352
a42e9724
JB
353 /* If a frame's focus has been redirected toward the currently
354 selected frame, we should change the redirection to point to the
355 newly selected frame. This means that if the focus is redirected
356 from a minibufferless frame to a surrogate minibuffer frame, we
357 can use `other-window' to switch between all the frames using
358 that minibuffer frame, and the focus redirection will follow us
359 around. */
360 {
361 Lisp_Object tail;
362
363 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
364 {
365 Lisp_Object focus;
366
367 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
368 abort ();
369
370 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
371
372 if (XTYPE (focus) == Lisp_Frame
373 && XFRAME (focus) == selected_frame)
374 Fredirect_frame_focus (XCONS (tail)->car, frame);
375 }
376 }
377
ff11dfa1
JB
378 selected_frame = XFRAME (frame);
379 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
380 last_nonminibuf_frame = selected_frame;
d5e7c279 381
ff11dfa1 382 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8
JB
383
384#ifdef HAVE_X_WINDOWS
ff11dfa1 385#ifdef MULTI_FRAME
fd0c2bd1 386 if (FRAME_X_P (XFRAME (frame))
265a9e55 387 && NILP (no_enter))
dc6f92b8 388 {
ff11dfa1 389 Ffocus_frame (frame);
dc6f92b8
JB
390 }
391#endif
392#endif
ff11dfa1 393 choose_minibuf_frame ();
dc6f92b8 394
ff11dfa1 395 return frame;
dc6f92b8
JB
396}
397
ff11dfa1
JB
398DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
399 "Return the frame that is now selected.")
dc6f92b8
JB
400 ()
401{
402 Lisp_Object tem;
ff11dfa1 403 XSET (tem, Lisp_Frame, selected_frame);
dc6f92b8
JB
404 return tem;
405}
406
ff11dfa1
JB
407DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
408 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
409 (window)
410 Lisp_Object window;
411{
774910eb 412 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 413 return XWINDOW (window)->frame;
dc6f92b8
JB
414}
415
ff11dfa1 416DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
417 "Returns the root-window of FRAME.\n\
418If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
419 (frame)
420 Lisp_Object frame;
dc6f92b8 421{
ff11dfa1
JB
422 if (NILP (frame))
423 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 424 else
ff11dfa1 425 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 426
ff11dfa1 427 return XFRAME (frame)->root_window;
dc6f92b8
JB
428}
429
ff11dfa1
JB
430DEFUN ("frame-selected-window", Fframe_selected_window,
431 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
432 "Return the selected window of frame object FRAME.\n\
433If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
434 (frame)
435 Lisp_Object frame;
dc6f92b8 436{
ff11dfa1
JB
437 if (NILP (frame))
438 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 439 else
ff11dfa1 440 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 441
ff11dfa1 442 return XFRAME (frame)->selected_window;
dc6f92b8
JB
443}
444
ff11dfa1 445DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 446 0, 0, 0,
ff11dfa1 447 "Return a list of all frames.")
dc6f92b8
JB
448 ()
449{
ff11dfa1 450 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
451}
452
ff11dfa1 453#ifdef MULTI_FRAME
f9898cc6 454
ff11dfa1 455/* Return the next frame in the frame list after FRAME.
ff11dfa1
JB
456 If MINIBUF is nil, exclude minibuffer-only frames.
457 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
458 their minibuffer.
459 If MINIBUF is non-nil, and not a window, include all frames. */
dc6f92b8 460Lisp_Object
ff11dfa1
JB
461next_frame (frame, minibuf)
462 Lisp_Object frame;
f9898cc6 463 Lisp_Object minibuf;
dc6f92b8
JB
464{
465 Lisp_Object tail;
466 int passed = 0;
467
ff11dfa1
JB
468 /* There must always be at least one frame in Vframe_list. */
469 if (! CONSP (Vframe_list))
f9898cc6
JB
470 abort ();
471
dc6f92b8 472 while (1)
ff11dfa1 473 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 474 {
d06a8a56
JB
475 Lisp_Object f = XCONS (tail)->car;
476
dc6f92b8 477 if (passed)
d5e7c279 478 {
d06a8a56
JB
479 /* Decide whether this frame is eligible to be returned. */
480
481 /* If we've looped all the way around without finding any
482 eligible frames, return the original frame. */
483 if (EQ (f, frame))
484 return f;
485
486 /* Let minibuf decide if this frame is acceptable. */
487 if (NILP (minibuf))
488 {
489 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
490 return f;
491 }
492 else if (XTYPE (minibuf) == Lisp_Window)
493 {
494 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
495 return f;
496 }
497 else
ff11dfa1 498 return f;
d5e7c279 499 }
dc6f92b8 500
d06a8a56 501 if (EQ (frame, f))
dc6f92b8
JB
502 passed++;
503 }
504}
505
d06a8a56
JB
506#if 0
507/* Nobody seems to be using this code right now. */
508
ff11dfa1 509/* Return the previous frame in the frame list before FRAME.
ff11dfa1
JB
510 If MINIBUF is nil, exclude minibuffer-only frames.
511 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
512 their minibuffer.
513 If MINIBUF is non-nil and not a window, include all frames. */
dc6f92b8 514Lisp_Object
ff11dfa1
JB
515prev_frame (frame, minibuf)
516 Lisp_Object frame;
f9898cc6 517 Lisp_Object minibuf;
dc6f92b8
JB
518{
519 Lisp_Object tail;
520 Lisp_Object prev;
521
ff11dfa1
JB
522 /* There must always be at least one frame in Vframe_list. */
523 if (! CONSP (Vframe_list))
f9898cc6
JB
524 abort ();
525
dc6f92b8 526 prev = Qnil;
d06a8a56 527 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 528 {
d06a8a56 529 Lisp_Object f = XCONS (tail)->car;
f9898cc6 530
d06a8a56
JB
531 if (XTYPE (f) != Lisp_Frame)
532 abort ();
f9898cc6 533
d06a8a56
JB
534 if (EQ (frame, f) && !NILP (prev))
535 return prev;
f9898cc6 536
d06a8a56
JB
537 /* Decide whether this frame is eligible to be returned,
538 according to minibuf. */
539 if (NILP (minibuf))
540 {
541 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
542 prev = f;
f9898cc6 543 }
d06a8a56
JB
544 else if (XTYPE (minibuf) == Lisp_Window)
545 {
546 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
547 prev = f;
548 }
549 else
550 prev = f;
f9898cc6 551 }
d06a8a56
JB
552
553 /* We've scanned the entire list. */
554 if (NILP (prev))
555 /* We went through the whole frame list without finding a single
556 acceptable frame. Return the original frame. */
557 return frame;
558 else
559 /* There were no acceptable frames in the list before FRAME; otherwise,
560 we would have returned directly from the loop. Since PREV is the last
561 acceptable frame in the list, return it. */
562 return prev;
dc6f92b8 563}
d06a8a56 564#endif
dc6f92b8 565
ff11dfa1
JB
566DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
567 "Return the next frame in the frame list after FRAME.\n\
a42e9724 568By default, skip minibuffer-only frames.\n\
d06a8a56 569If omitted, FRAME defaults to the selected frame.\n\
8693ca83
JB
570If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
571If MINIFRAME is a window, include only frames using that window for their\n\
d06a8a56 572minibuffer.\n\
8693ca83 573If MINIFRAME is non-nil and not a window, include all frames.")
ff11dfa1 574 (frame, miniframe)
8693ca83 575 Lisp_Object frame, miniframe;
dc6f92b8
JB
576{
577 Lisp_Object tail;
578
ff11dfa1
JB
579 if (NILP (frame))
580 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 581 else
ff11dfa1 582 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 583
ff11dfa1 584 return next_frame (frame, miniframe);
dc6f92b8 585}
ff11dfa1 586#endif /* MULTI_FRAME */
dc6f92b8 587\f
ff11dfa1
JB
588DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
589 "Delete FRAME, permanently eliminating it from use.\n\
590If omitted, FRAME defaults to the selected frame.\n\
591A frame may not be deleted if its minibuffer is used by other frames.")
592 (frame)
593 Lisp_Object frame;
dc6f92b8 594{
ff11dfa1 595 struct frame *f;
dc6f92b8
JB
596 union display displ;
597
ff11dfa1 598 if (EQ (frame, Qnil))
dc6f92b8 599 {
ff11dfa1
JB
600 f = selected_frame;
601 XSET (frame, Lisp_Frame, f);
dc6f92b8
JB
602 }
603 else
604 {
ff11dfa1
JB
605 CHECK_FRAME (frame, 0);
606 f = XFRAME (frame);
dc6f92b8
JB
607 }
608
ff11dfa1 609 if (! FRAME_LIVE_P (f))
f9898cc6
JB
610 return;
611
ff11dfa1
JB
612 /* Are there any other frames besides this one? */
613 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
614 error ("Attempt to delete the only frame");
d5e7c279 615
ff11dfa1
JB
616 /* Does this frame have a minibuffer, and is it the surrogate
617 minibuffer for any other frame? */
fd0c2bd1 618 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 619 {
ff11dfa1 620 Lisp_Object frames;
1113d9db 621
ff11dfa1
JB
622 for (frames = Vframe_list;
623 CONSP (frames);
624 frames = XCONS (frames)->cdr)
1113d9db 625 {
ff11dfa1 626 Lisp_Object this = XCONS (frames)->car;
1113d9db 627
ff11dfa1
JB
628 if (! EQ (this, frame)
629 && EQ (frame,
630 (WINDOW_FRAME
1113d9db 631 (XWINDOW
ff11dfa1
JB
632 (FRAME_MINIBUF_WINDOW
633 (XFRAME (this)))))))
634 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 635 }
dc6f92b8
JB
636 }
637
ff11dfa1
JB
638 /* Don't let the frame remain selected. */
639 if (f == selected_frame)
629a12cf 640 Fselect_frame (next_frame (frame, Qt), Qnil);
dc6f92b8 641
ff11dfa1
JB
642 /* Don't allow minibuf_window to remain on a deleted frame. */
643 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 644 {
ff11dfa1 645 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 646 XWINDOW (minibuf_window)->buffer);
ff11dfa1 647 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
648 }
649
4a88b3b0
JB
650 /* Mark all the windows that used to be on FRAME as deleted, and then
651 remove the reference to them. */
652 delete_all_subwindows (XWINDOW (f->root_window));
653 f->root_window = Qnil;
654
ff11dfa1 655 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 656 FRAME_SET_VISIBLE (f, 0);
ff11dfa1
JB
657 displ = f->display;
658 f->display.nothing = 0;
dc6f92b8 659
d5e7c279 660#ifdef HAVE_X_WINDOWS
fd0c2bd1 661 if (FRAME_X_P (f))
ff11dfa1 662 x_destroy_window (f, displ);
d5e7c279
JB
663#endif
664
ff11dfa1 665 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 666 another one. */
ff11dfa1 667 if (f == last_nonminibuf_frame)
d5e7c279 668 {
ff11dfa1 669 Lisp_Object frames;
1113d9db 670
ff11dfa1 671 last_nonminibuf_frame = 0;
d5e7c279 672
ff11dfa1
JB
673 for (frames = Vframe_list;
674 CONSP (frames);
675 frames = XCONS (frames)->cdr)
d5e7c279 676 {
ff11dfa1
JB
677 f = XFRAME (XCONS (frames)->car);
678 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 679 {
ff11dfa1 680 last_nonminibuf_frame = f;
d5e7c279
JB
681 break;
682 }
683 }
684 }
dc6f92b8 685
ff11dfa1
JB
686 /* If we've deleted Vdefault_minibuffer_frame, try to find another
687 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 688 with other windows. */
ff11dfa1 689 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 690 {
ff11dfa1 691 Lisp_Object frames;
1113d9db 692
ff11dfa1
JB
693 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
694 Lisp_Object frame_with_minibuf = Qnil;
1113d9db 695
ff11dfa1
JB
696 for (frames = Vframe_list;
697 CONSP (frames);
698 frames = XCONS (frames)->cdr)
1113d9db 699 {
ff11dfa1 700 Lisp_Object this = XCONS (frames)->car;
1113d9db 701
ff11dfa1 702 if (XTYPE (this) != Lisp_Frame)
1113d9db 703 abort ();
ff11dfa1 704 f = XFRAME (this);
1113d9db 705
fd0c2bd1 706 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 707 {
ff11dfa1
JB
708 frame_with_minibuf = this;
709 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
710 break;
711 }
712 }
713
ff11dfa1
JB
714 /* We know that there must be some frame with a minibuffer out
715 there. If this were not true, all of the frames present
1113d9db 716 would have to be minibufferless, which implies that at some
ff11dfa1 717 point their minibuffer frames must have been deleted, but
1113d9db 718 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
719 minibuffer frames. */
720 if (NILP (frame_with_minibuf))
1113d9db
JB
721 abort ();
722
ff11dfa1 723 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
724 }
725
dc6f92b8
JB
726 return Qnil;
727}
728\f
729/* Return mouse position in character cell units. */
730
f9898cc6 731DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 732 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
f9898cc6 733If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 734to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
735and nil for X and Y.")
736 ()
dc6f92b8 737{
f9898cc6 738 Lisp_Object x, y, dummy;
ff11dfa1 739 FRAME_PTR f;
dc6f92b8 740
f9898cc6 741 if (mouse_position_hook)
ff11dfa1 742 (*mouse_position_hook) (&f, &x, &y, &dummy);
f9898cc6
JB
743 else
744 {
ff11dfa1 745 f = selected_frame;
f9898cc6
JB
746 x = y = Qnil;
747 }
dc6f92b8 748
ff11dfa1 749 XSET (dummy, Lisp_Frame, f);
f9898cc6 750 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
dc6f92b8
JB
751}
752
753DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
ff11dfa1
JB
754 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
755WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
756 (frame, x, y)
757 Lisp_Object frame, x, y;
dc6f92b8 758{
ff11dfa1 759 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
760 CHECK_NUMBER (x, 2);
761 CHECK_NUMBER (y, 1);
762
763#ifdef HAVE_X_WINDOWS
fd0c2bd1 764 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 765 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 766 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
767#endif
768
769 return Qnil;
770}
771\f
772#if 0
773/* ??? Can this be replaced with a Lisp function?
06b1a5ef
JB
774 It is used in minibuf.c. Can we get rid of that?
775 Yes. All uses in minibuf.c are gone, and parallels to these
ff11dfa1 776 functions have been defined in frame.el. */
dc6f92b8 777
ff11dfa1 778DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
dc6f92b8 779 0, 0, 0,
ff11dfa1
JB
780 "Return object describing current frame configuration.\n\
781The frame configuration is the current mouse position and selected frame.\n\
782This object can be given to `restore-frame-configuration'\n\
783to restore this frame configuration.")
dc6f92b8
JB
784 ()
785{
f9898cc6 786 Lisp_Object c, time;
dc6f92b8 787
f9898cc6 788 c = Fmake_vector (make_number(4), Qnil);
ff11dfa1 789 XVECTOR (c)->contents[0] = Fselected_frame();
f9898cc6
JB
790 if (mouse_position_hook)
791 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
792 &XVECTOR (c)->contents[2],
793 &XVECTOR (c)->contents[3],
794 &time);
dc6f92b8
JB
795 return c;
796}
797
ff11dfa1
JB
798DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
799 Srestore_frame_configuration,
dc6f92b8 800 1, 1, 0,
ff11dfa1 801 "Restores frame configuration CONFIGURATION.")
dc6f92b8
JB
802 (config)
803 Lisp_Object config;
804{
ff11dfa1 805 Lisp_Object x_pos, y_pos, frame;
dc6f92b8
JB
806
807 CHECK_VECTOR (config, 0);
808 if (XVECTOR (config)->size != 3)
809 {
ff11dfa1 810 error ("Wrong size vector passed to restore-frame-configuration");
dc6f92b8 811 }
ff11dfa1
JB
812 frame = XVECTOR (config)->contents[0];
813 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 814
ff11dfa1 815 Fselect_frame (frame, Qnil);
dc6f92b8
JB
816
817#if 0
ff11dfa1 818 /* This seems to interfere with the frame selection mechanism. jla */
f9898cc6
JB
819 x_pos = XVECTOR (config)->contents[2];
820 y_pos = XVECTOR (config)->contents[3];
ff11dfa1 821 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
dc6f92b8
JB
822#endif
823
ff11dfa1 824 return frame;
dc6f92b8
JB
825}
826#endif
827\f
ff11dfa1 828DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1aa66088 829 0, 1, 0,
ff11dfa1 830 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83
JB
831Also raises the frame so that nothing obscures it.\n\
832If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
833 (frame)
834 Lisp_Object frame;
dc6f92b8 835{
1aa66088 836 if (NILP (frame))
7500877e 837 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 838
ff11dfa1 839 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 840
fd0c2bd1
JB
841#ifdef HAVE_X_WINDOWS
842 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 843 x_make_frame_visible (XFRAME (frame));
fd0c2bd1 844#endif
dc6f92b8 845
ff11dfa1 846 return frame;
dc6f92b8
JB
847}
848
ff11dfa1 849DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1aa66088 850 0, 1, "",
8693ca83
JB
851 "Make the frame FRAME invisible (assuming it is an X-window).\n\
852If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
853 (frame)
854 Lisp_Object frame;
dc6f92b8 855{
1aa66088 856 if (NILP (frame))
7500877e 857 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 858
ff11dfa1 859 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 860
fd0c2bd1
JB
861#ifdef HAVE_X_WINDOWS
862 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 863 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 864#endif
dc6f92b8
JB
865
866 return Qnil;
867}
868
ff11dfa1 869DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 870 0, 1, "",
8693ca83
JB
871 "Make the frame FRAME into an icon.\n\
872If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
873 (frame)
874 Lisp_Object frame;
dc6f92b8 875{
1aa66088 876 if (NILP (frame))
7500877e 877 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 878
ff11dfa1 879 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 880
fd0c2bd1
JB
881#ifdef HAVE_X_WINDOWS
882 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 883 x_iconify_frame (XFRAME (frame));
fd0c2bd1 884#endif
dc6f92b8
JB
885
886 return Qnil;
887}
888
ff11dfa1 889DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 890 1, 1, 0,
ff11dfa1
JB
891 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
892A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 893a window system, it may not show at all.\n\
fd0c2bd1 894Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
895 (frame)
896 Lisp_Object frame;
dc6f92b8 897{
ff11dfa1 898 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 899
a42e9724 900 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 901 return Qt;
a42e9724 902 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 903 return Qicon;
dc6f92b8
JB
904 return Qnil;
905}
906
ff11dfa1 907DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 908 0, 0, 0,
ff11dfa1 909 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
910 ()
911{
ff11dfa1
JB
912 Lisp_Object tail, frame;
913 struct frame *f;
dc6f92b8
JB
914 Lisp_Object value;
915
916 value = Qnil;
ff11dfa1 917 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 918 {
ff11dfa1
JB
919 frame = XCONS (tail)->car;
920 if (XTYPE (frame) != Lisp_Frame)
dc6f92b8 921 continue;
ff11dfa1 922 f = XFRAME (frame);
a42e9724 923 if (FRAME_VISIBLE_P (f))
ff11dfa1 924 value = Fcons (frame, value);
dc6f92b8
JB
925 }
926 return value;
927}
d5e7c279
JB
928
929
930\f
ff11dfa1 931DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 932 1, 2, 0,
ff11dfa1 933 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
934In other words, switch-frame events caused by events in FRAME will\n\
935request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
936FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 937\n\
a42e9724 938If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 939cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 940\n\
a42e9724
JB
941Focus redirection is useful for temporarily redirecting keystrokes to\n\
942a surrogate minibuffer frame when a frame doesn't have its own\n\
943minibuffer window.\n\
d5e7c279 944\n\
a42e9724
JB
945A frame's focus redirection can be changed by select-frame. If frame\n\
946FOO is selected, and then a different frame BAR is selected, any\n\
947frames redirecting their focus to FOO are shifted to redirect their\n\
948focus to BAR. This allows focus redirection to work properly when the\n\
949user switches from one frame to another using `select-window'.\n\
950\n\
951This means that a frame whose focus is redirected to itself is treated\n\
952differently from a frame whose focus is redirected to nil; the former\n\
953is affected by select-frame, while the latter is not.\n\
954\n\
955The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
956 (frame, focus_frame)
957 Lisp_Object frame, focus_frame;
d5e7c279 958{
ff11dfa1 959 CHECK_LIVE_FRAME (frame, 0);
f9898cc6 960
a42e9724 961 if (! NILP (focus_frame))
ff11dfa1 962 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 963
ff11dfa1 964 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 965
ff11dfa1
JB
966 if (frame_rehighlight_hook)
967 (*frame_rehighlight_hook) ();
d5e7c279
JB
968
969 return Qnil;
970}
971
972
ff11dfa1
JB
973DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
974 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 975This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
976See `redirect-frame-focus'.")
977 (frame)
978 Lisp_Object frame;
d5e7c279 979{
ff11dfa1 980 CHECK_LIVE_FRAME (frame, 0);
a42e9724 981
ff11dfa1 982 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
983}
984
985
dc6f92b8
JB
986\f
987Lisp_Object
ff11dfa1
JB
988get_frame_param (frame, prop)
989 register struct frame *frame;
dc6f92b8
JB
990 Lisp_Object prop;
991{
992 register Lisp_Object tem;
993
ff11dfa1 994 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
995 if (EQ (tem, Qnil))
996 return tem;
997 return Fcdr (tem);
998}
999
1000void
fd0c2bd1 1001store_in_alist (alistptr, prop, val)
dc6f92b8 1002 Lisp_Object *alistptr, val;
fd0c2bd1 1003 Lisp_Object prop;
dc6f92b8
JB
1004{
1005 register Lisp_Object tem;
dc6f92b8 1006
dc6f92b8
JB
1007 tem = Fassq (prop, *alistptr);
1008 if (EQ (tem, Qnil))
1009 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1010 else
1011 Fsetcdr (tem, val);
1012}
1013
1014void
ff11dfa1
JB
1015store_frame_param (f, prop, val)
1016 struct frame *f;
dc6f92b8
JB
1017 Lisp_Object prop, val;
1018{
1019 register Lisp_Object tem;
1020
ff11dfa1 1021 tem = Fassq (prop, f->param_alist);
dc6f92b8 1022 if (EQ (tem, Qnil))
ff11dfa1 1023 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1024 else
1025 Fsetcdr (tem, val);
bc93c097
JB
1026
1027 if (EQ (prop, Qminibuffer)
1028 && XTYPE (val) == Lisp_Window)
1029 {
1030 if (! MINI_WINDOW_P (XWINDOW (val)))
1031 error ("Surrogate minibuffer windows must be minibuffer windows.");
1032
fd0c2bd1 1033 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
ff11dfa1 1034 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
bc93c097
JB
1035
1036 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1037 f->minibuffer_window = val;
bc93c097 1038 }
dc6f92b8
JB
1039}
1040
ff11dfa1
JB
1041DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1042 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1043It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1044The meaningful PARMs depend on the kind of frame.\n\
1045If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1046 (frame)
1047 Lisp_Object frame;
dc6f92b8
JB
1048{
1049 Lisp_Object alist;
ff11dfa1 1050 struct frame *f;
dc6f92b8 1051
ff11dfa1
JB
1052 if (EQ (frame, Qnil))
1053 f = selected_frame;
dc6f92b8
JB
1054 else
1055 {
ff11dfa1
JB
1056 CHECK_FRAME (frame, 0);
1057 f = XFRAME (frame);
dc6f92b8
JB
1058 }
1059
ff11dfa1 1060 if (f->display.nothing == 0)
dc6f92b8
JB
1061 return Qnil;
1062
ff11dfa1 1063 alist = Fcopy_alist (f->param_alist);
fd0c2bd1
JB
1064 store_in_alist (&alist, Qname, f->name);
1065 store_in_alist (&alist, Qheight, make_number (f->height));
1066 store_in_alist (&alist, Qwidth, make_number (f->width));
1067 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1068 store_in_alist (&alist, Qminibuffer,
1069 (! FRAME_HAS_MINIBUF_P (f) ? Qnone
1070 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1071 : FRAME_MINIBUF_WINDOW (f))));
1072 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1073
1074#ifdef HAVE_X_WINDOWS
1075 if (FRAME_X_P (f))
ff11dfa1 1076 x_report_frame_params (f, &alist);
fd0c2bd1 1077#endif
dc6f92b8
JB
1078 return alist;
1079}
1080
ff11dfa1
JB
1081DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1082 Smodify_frame_parameters, 2, 2, 0,
1083 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1084ALIST is an alist of parameters to change and their new values.\n\
1085Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1086The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1087 (frame, alist)
1088 Lisp_Object frame, alist;
dc6f92b8 1089{
fd0c2bd1 1090 FRAME_PTR f;
dc6f92b8
JB
1091 register Lisp_Object tail, elt, prop, val;
1092
ff11dfa1
JB
1093 if (EQ (frame, Qnil))
1094 f = selected_frame;
dc6f92b8
JB
1095 else
1096 {
ff11dfa1
JB
1097 CHECK_LIVE_FRAME (frame, 0);
1098 f = XFRAME (frame);
dc6f92b8
JB
1099 }
1100
fd0c2bd1
JB
1101#ifdef HAVE_X_WINDOWS
1102 if (FRAME_X_P (f))
1103#if 1
1104 x_set_frame_parameters (f, alist);
1105#else
dc6f92b8
JB
1106 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1107 {
1108 elt = Fcar (tail);
1109 prop = Fcar (elt);
1110 val = Fcdr (elt);
fd0c2bd1 1111 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
ff11dfa1 1112 store_frame_param (f, prop, val);
dc6f92b8 1113 }
fd0c2bd1
JB
1114#endif
1115#endif
dc6f92b8
JB
1116
1117 return Qnil;
1118}
1119\f
1120
dc6d9681
JB
1121#if 0
1122/* This function isn't useful enough by itself to include; we need to
1123 add functions to allow the user to find the size of a font before
1124 this is actually useful. */
1125
ff11dfa1
JB
1126DEFUN ("frame-pixel-size", Fframe_pixel_size,
1127 Sframe_pixel_size, 1, 1, 0,
1128 "Return a cons (width . height) of FRAME's size in pixels.")
1129 (frame)
1130 Lisp_Object frame;
dc6f92b8 1131{
ff11dfa1 1132 register struct frame *f;
dc6f92b8
JB
1133 int width, height;
1134
ff11dfa1
JB
1135 CHECK_LIVE_FRAME (frame, 0);
1136 f = XFRAME (frame);
dc6f92b8 1137
ff11dfa1
JB
1138 return Fcons (make_number (x_pixel_width (f)),
1139 make_number (x_pixel_height (f)));
dc6f92b8 1140}
dc6d9681
JB
1141#endif
1142
1143#if 0
1144/* These functions have no C callers, and can be written nicely in lisp. */
dc6f92b8 1145
ff11dfa1
JB
1146DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1147 "Return number of lines available for display on selected frame.")
dc6f92b8
JB
1148 ()
1149{
ff11dfa1 1150 return make_number (FRAME_HEIGHT (selected_frame));
dc6f92b8
JB
1151}
1152
ff11dfa1
JB
1153DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1154 "Return number of columns available for display on selected frame.")
dc6f92b8
JB
1155 ()
1156{
ff11dfa1 1157 return make_number (FRAME_WIDTH (selected_frame));
dc6f92b8 1158}
dc6d9681 1159#endif
dc6f92b8 1160
ff11dfa1
JB
1161DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1162 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1163Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1164but that the idea of the actual height of the frame should not be changed.")
1165 (frame, rows, pretend)
fd0c2bd1 1166 Lisp_Object frame, rows, pretend;
dc6f92b8 1167{
ff11dfa1 1168 register struct frame *f;
dc6f92b8
JB
1169
1170 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1171 if (NILP (frame))
1172 f = selected_frame;
dc6f92b8
JB
1173 else
1174 {
ff11dfa1
JB
1175 CHECK_LIVE_FRAME (frame, 0);
1176 f = XFRAME (frame);
dc6f92b8
JB
1177 }
1178
fd0c2bd1
JB
1179#ifdef HAVE_X_WINDOWS
1180 if (FRAME_X_P (f))
dc6f92b8 1181 {
ff11dfa1
JB
1182 if (XINT (rows) != f->width)
1183 x_set_window_size (f, f->width, XINT (rows));
dc6f92b8
JB
1184 }
1185 else
fd0c2bd1
JB
1186#endif
1187 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1188 return Qnil;
1189}
1190
ff11dfa1
JB
1191DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1192 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1193Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1194but that the idea of the actual width of the frame should not be changed.")
1195 (frame, cols, pretend)
fd0c2bd1 1196 Lisp_Object frame, cols, pretend;
dc6f92b8 1197{
ff11dfa1 1198 register struct frame *f;
dc6f92b8 1199 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1200 if (NILP (frame))
1201 f = selected_frame;
dc6f92b8
JB
1202 else
1203 {
ff11dfa1
JB
1204 CHECK_LIVE_FRAME (frame, 0);
1205 f = XFRAME (frame);
dc6f92b8
JB
1206 }
1207
fd0c2bd1
JB
1208#ifdef HAVE_X_WINDOWS
1209 if (FRAME_X_P (f))
dc6f92b8 1210 {
ff11dfa1
JB
1211 if (XINT (cols) != f->width)
1212 x_set_window_size (f, XINT (cols), f->height);
dc6f92b8
JB
1213 }
1214 else
fd0c2bd1
JB
1215#endif
1216 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1217 return Qnil;
1218}
1219
ff11dfa1
JB
1220DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1221 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1222 (frame, cols, rows)
1223 Lisp_Object frame, cols, rows;
dc6f92b8 1224{
ff11dfa1 1225 register struct frame *f;
dc6f92b8
JB
1226 int mask;
1227
ff11dfa1 1228 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1229 CHECK_NUMBER (cols, 2);
1230 CHECK_NUMBER (rows, 1);
ff11dfa1 1231 f = XFRAME (frame);
dc6f92b8 1232
fd0c2bd1
JB
1233#ifdef HAVE_X_WINDOWS
1234 if (FRAME_X_P (f))
dc6f92b8 1235 {
ff11dfa1
JB
1236 if (XINT (rows) != f->height || XINT (cols) != f->width)
1237 x_set_window_size (f, XINT (cols), XINT (rows));
dc6f92b8
JB
1238 }
1239 else
fd0c2bd1
JB
1240#endif
1241 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1242
1243 return Qnil;
1244}
1245
ff11dfa1
JB
1246DEFUN ("set-frame-position", Fset_frame_position,
1247 Sset_frame_position, 3, 3, 0,
1248 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
f9898cc6 1249If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
ff11dfa1 1250the leftmost or bottommost position FRAME could occupy without going\n\
fd0c2bd1 1251off the screen.")
ff11dfa1
JB
1252 (frame, xoffset, yoffset)
1253 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1254{
ff11dfa1 1255 register struct frame *f;
dc6f92b8
JB
1256 int mask;
1257
ff11dfa1 1258 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1259 CHECK_NUMBER (xoffset, 1);
1260 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1261 f = XFRAME (frame);
dc6f92b8 1262
fd0c2bd1
JB
1263#ifdef HAVE_X_WINDOWS
1264 if (FRAME_X_P (f))
ff11dfa1 1265 x_set_offset (f, XINT (xoffset), XINT (yoffset));
fd0c2bd1 1266#endif
dc6f92b8
JB
1267
1268 return Qt;
1269}
dc6d9681 1270
dc6f92b8 1271\f
dc6f92b8
JB
1272#ifndef HAVE_X11
1273DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1274 3, 3, "",
ff11dfa1
JB
1275 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1276Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
dc6f92b8
JB
1277the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1278specify defaults for some sizes/positions. If GEO specifies everything,\n\
1279the mouse is not used.\n\
ff11dfa1
JB
1280Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1281 (frame, name, geo)
1282 Lisp_Object frame;
dc6f92b8
JB
1283 Lisp_Object name;
1284 Lisp_Object geo;
1285{
1286 int vals[4];
1287 Lisp_Object nums[4];
1288 int i;
1289
ff11dfa1 1290 CHECK_FRAME (frame, 0);
dc6f92b8
JB
1291 CHECK_STRING (name, 1);
1292 CHECK_STRING (geo, 2);
1293
ff11dfa1 1294 switch (XFRAME (frame)->output_method)
dc6f92b8
JB
1295 {
1296 case output_x_window:
ff11dfa1 1297 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
dc6f92b8
JB
1298 XSTRING (geo)->data, XSTRING (name)->data);
1299 break;
1300
1301 default:
1302 return Qnil;
1303 }
1304
1305 for (i = 0; i < 4; i++)
1306 XFASTINT (nums[i]) = vals[i];
ff11dfa1 1307 return Fcons (frame, Flist (4, nums));
dc6f92b8
JB
1308 return Qnil;
1309}
1310#endif /* not HAVE_X11 */
1311\f
ff11dfa1 1312choose_minibuf_frame ()
dc6f92b8 1313{
ff11dfa1
JB
1314 /* For lowest-level minibuf, put it on currently selected frame
1315 if frame has a minibuffer. */
d06a8a56 1316
dc6f92b8 1317 if (minibuf_level == 0
ff11dfa1 1318 && selected_frame != 0
d06a8a56 1319 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1320 {
d06a8a56
JB
1321 /* I don't think that any frames may validly have a null minibuffer
1322 window anymore. */
1323 if (NILP (selected_frame->minibuffer_window))
1324 abort ();
1325
ff11dfa1 1326 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1327 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1328 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1329 }
1330}
1331\f
ff11dfa1 1332syms_of_frame ()
dc6f92b8 1333{
fd0c2bd1 1334 /*&&& init symbols here &&&*/
ff11dfa1 1335 Qframep = intern ("framep");
ff11dfa1 1336 staticpro (&Qframep);
fd0c2bd1 1337 Qlive_frame_p = intern ("live-frame-p");
ff11dfa1 1338 staticpro (&Qlive_frame_p);
fd0c2bd1
JB
1339 Qheight = intern ("height");
1340 staticpro (&Qheight);
1341 Qicon = intern ("icon");
1342 staticpro (&Qicon);
1343 Qminibuffer = intern ("minibuffer");
bc93c097 1344 staticpro (&Qminibuffer);
fd0c2bd1
JB
1345 Qmodeline = intern ("modeline");
1346 staticpro (&Qmodeline);
1347 Qname = intern ("name");
1348 staticpro (&Qname);
1349 Qnone = intern ("none");
1350 staticpro (&Qnone);
1351 Qonly = intern ("only");
1352 staticpro (&Qonly);
1353 Qunsplittable = intern ("unsplittable");
1354 staticpro (&Qunsplittable);
1355 Qwidth = intern ("width");
1356 staticpro (&Qwidth);
1357 Qx = intern ("x");
1358 staticpro (&Qx);
dc6f92b8 1359
ff11dfa1 1360 staticpro (&Vframe_list);
dc6f92b8 1361
ff11dfa1
JB
1362 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1363 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1364
1365 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1366 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1367 Vemacs_iconified = Qnil;
1368
ff11dfa1
JB
1369 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1370 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1371\n\
ff11dfa1 1372Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1373appropriate surrogate.\n\
1374\n\
1375Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1376frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1377minibuffer, no matter what this variable is set to. This means that\n\
1378this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1379current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1380displayed.");
ff11dfa1 1381 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1382
ff11dfa1
JB
1383 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1384 "Alist of default values for frame creation.\n\
5bce042c 1385These may be set in your init file, like this:\n\
ff11dfa1 1386 (setq default-frame-alist '((width . 80) (height . 55)))\n\
5bce042c
JB
1387These override values given in window system configuration data, like\n\
1388X Windows' defaults database.\n\
ff11dfa1
JB
1389For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1390For values specific to the separate minibuffer frame, see\n\
1391`minibuffer-frame-alist'.");
1392 Vdefault_frame_alist = Qnil;
1393
1394 defsubr (&Sframep);
1395 defsubr (&Slive_frame_p);
1396 defsubr (&Sselect_frame);
1397 defsubr (&Sselected_frame);
1398 defsubr (&Swindow_frame);
1399 defsubr (&Sframe_root_window);
1400 defsubr (&Sframe_selected_window);
1401 defsubr (&Sframe_list);
1402 defsubr (&Snext_frame);
1403 defsubr (&Sdelete_frame);
f9898cc6 1404 defsubr (&Smouse_position);
dc6f92b8
JB
1405 defsubr (&Sset_mouse_position);
1406#if 0
ff11dfa1
JB
1407 defsubr (&Sframe_configuration);
1408 defsubr (&Srestore_frame_configuration);
dc6f92b8 1409#endif
ff11dfa1
JB
1410 defsubr (&Smake_frame_visible);
1411 defsubr (&Smake_frame_invisible);
1412 defsubr (&Siconify_frame);
1413 defsubr (&Sframe_visible_p);
1414 defsubr (&Svisible_frame_list);
1415 defsubr (&Sredirect_frame_focus);
1416 defsubr (&Sframe_focus);
1417 defsubr (&Sframe_parameters);
1418 defsubr (&Smodify_frame_parameters);
1265558a 1419#if 0
ff11dfa1
JB
1420 defsubr (&Sframe_pixel_size);
1421 defsubr (&Sframe_height);
1422 defsubr (&Sframe_width);
1265558a 1423#endif
ff11dfa1
JB
1424 defsubr (&Sset_frame_height);
1425 defsubr (&Sset_frame_width);
1426 defsubr (&Sset_frame_size);
1427 defsubr (&Sset_frame_position);
dc6f92b8
JB
1428#ifndef HAVE_X11
1429 defsubr (&Srubber_band_rectangle);
1430#endif /* HAVE_X11 */
1431}
e5d77022 1432
2f0b07e0
JB
1433keys_of_frame ()
1434{
1435 initial_define_lispy_key (global_map, "switch-frame", "select-frame");
1436}
1437
d06a8a56 1438#else /* not MULTI_FRAME */
fd0c2bd1 1439
cc38027b
JB
1440/* If we're not using multi-frame stuff, we still need to provide some
1441 support functions. */
1442
1443/* Unless this function is defined, providing set-frame-height and
1444 set-frame-width doesn't help compatibility any, since they both
1445 want this as their first argument. */
1446DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1447 "Return the frame that is now selected.")
1448 ()
1449{
1450 Lisp_Object tem;
1451 XFASTINT (tem) = 0;
1452 return tem;
1453}
fd0c2bd1
JB
1454
1455DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1456 "Specify that the frame FRAME has LINES lines.\n\
1457Optional third arg non-nil means that redisplay should use LINES lines\n\
1458but that the idea of the actual height of the frame should not be changed.")
1459 (frame, rows, pretend)
1460 Lisp_Object frame, rows, pretend;
1461{
1462 CHECK_NUMBER (rows, 0);
1463
1464 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1465 return Qnil;
1466}
1467
1468DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1469 "Specify that the frame FRAME has COLS columns.\n\
1470Optional third arg non-nil means that redisplay should use COLS columns\n\
1471but that the idea of the actual width of the frame should not be changed.")
1472 (frame, cols, pretend)
1473 Lisp_Object frame, cols, pretend;
1474{
1475 CHECK_NUMBER (cols, 0);
1476
1477 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1478 return Qnil;
1479}
1480
1481DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1482 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1483 (frame, cols, rows)
1484 Lisp_Object frame, cols, rows;
1485{
1486 CHECK_NUMBER (cols, 2);
1487 CHECK_NUMBER (rows, 1);
1488
1489 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1490
1491 return Qnil;
1492}
1493
cc38027b
JB
1494DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1495 "Return number of lines available for display on selected frame.")
1496 ()
1497{
1498 return make_number (FRAME_HEIGHT (selected_frame));
1499}
1500
1501DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1502 "Return number of columns available for display on selected frame.")
1503 ()
1504{
1505 return make_number (FRAME_WIDTH (selected_frame));
1506}
1507
1508/* These are for backward compatibility with Emacs 18. */
1509
fd0c2bd1
JB
1510DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1511 "Tell redisplay that the screen has LINES lines.\n\
1512Optional second arg non-nil means that redisplay should use LINES lines\n\
1513but that the idea of the actual height of the screen should not be changed.")
1514 (lines, pretend)
1515 Lisp_Object lines, pretend;
1516{
1517 CHECK_NUMBER (lines, 0);
1518
1519 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1520 return Qnil;
1521}
1522
1523DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1524 "Tell redisplay that the screen has COLS columns.\n\
1525Optional second arg non-nil means that redisplay should use COLS columns\n\
1526but that the idea of the actual width of the screen should not be changed.")
1527 (cols, pretend)
1528 Lisp_Object cols, pretend;
1529{
1530 CHECK_NUMBER (cols, 0);
1531
1532 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1533 return Qnil;
1534}
1535
fd0c2bd1
JB
1536syms_of_frame ()
1537{
1538 defsubr (&Sset_frame_height);
1539 defsubr (&Sset_frame_width);
1540 defsubr (&Sset_frame_size);
1541 defsubr (&Sset_screen_height);
1542 defsubr (&Sset_screen_width);
1543 defsubr (&Sframe_height);
1544 Ffset (intern ("screen-height"), intern ("frame-height"));
1545 defsubr (&Sframe_width);
1546 Ffset (intern ("screen-width"), intern ("frame-width"));
1547}
1548
2f0b07e0
JB
1549keys_of_frame ()
1550{
1551}
1552
fd0c2bd1
JB
1553#endif /* not MULTI_FRAME */
1554
1555
1556
1557