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