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