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