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