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