entered into RCS
[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"
cc38027b
JB
23#include "lisp.h"
24#include "frame.h"
e5d77022 25
ff11dfa1 26#ifdef MULTI_FRAME
e5d77022 27
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;
804518aa 153 f->explicit_name = 0;
ff11dfa1
JB
154
155 f->param_alist = Qnil;
dc6f92b8 156
cc38027b 157 root_window = make_window ();
dc6f92b8
JB
158 if (mini_p)
159 {
cc38027b 160 mini_window = make_window ();
dc6f92b8
JB
161 XWINDOW (root_window)->next = mini_window;
162 XWINDOW (mini_window)->prev = root_window;
163 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
164 XWINDOW (mini_window)->frame = frame;
165 f->minibuffer_window = mini_window;
dc6f92b8
JB
166 }
167 else
168 {
169 mini_window = Qnil;
170 XWINDOW (root_window)->next = Qnil;
ff11dfa1 171 f->minibuffer_window = Qnil;
dc6f92b8
JB
172 }
173
ff11dfa1 174 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
175
176 /* 10 is arbitrary,
177 just so that there is "something there."
ff11dfa1 178 Correct size will be set up later with change_frame_size. */
dc6f92b8 179
ff11dfa1
JB
180 f->width = 10;
181 f->height = 10;
dc6f92b8
JB
182
183 XFASTINT (XWINDOW (root_window)->width) = 10;
184 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
185
186 if (mini_p)
187 {
188 XFASTINT (XWINDOW (mini_window)->width) = 10;
189 XFASTINT (XWINDOW (mini_window)->top) = 9;
190 XFASTINT (XWINDOW (mini_window)->height) = 1;
191 }
192
ff11dfa1 193 /* Choose a buffer for the frame's root window. */
5bce042c
JB
194 {
195 Lisp_Object buf;
196
197 XWINDOW (root_window)->buffer = Qt;
198 buf = Fcurrent_buffer ();
199 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
200 a space), try to find another one. */
201 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
202 buf = Fother_buffer (buf);
203 Fset_window_buffer (root_window, buf);
204 }
205
dc6f92b8
JB
206 if (mini_p)
207 {
208 XWINDOW (mini_window)->buffer = Qt;
209 Fset_window_buffer (mini_window,
265a9e55 210 (NILP (Vminibuffer_list)
dc6f92b8
JB
211 ? get_minibuffer (0)
212 : Fcar (Vminibuffer_list)));
213 }
214
ff11dfa1
JB
215 f->root_window = root_window;
216 f->selected_window = root_window;
d5e7c279
JB
217 /* Make sure this window seems more recently used than
218 a newly-created, never-selected window. */
ff11dfa1 219 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
dc6f92b8 220
ff11dfa1 221 Vframe_list = Fcons (frame, Vframe_list);
dc6f92b8 222
ff11dfa1 223 return f;
dc6f92b8
JB
224}
225\f
ff11dfa1 226/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
227 MINI_WINDOW is the minibuffer window to use. nil means use the
228 default (the global minibuffer). */
229
ff11dfa1
JB
230struct frame *
231make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
232 register Lisp_Object mini_window;
233{
ff11dfa1 234 register struct frame *f;
dc6f92b8
JB
235
236 /* Choose the minibuffer window to use. */
265a9e55 237 if (NILP (mini_window))
dc6f92b8 238 {
ff11dfa1
JB
239 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
240 error ("default-minibuffer-frame must be set when creating minibufferless frames");
241 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
242 error ("default-minibuffer-frame must be a live frame");
243 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
244 }
245 else
246 {
247 CHECK_WINDOW (mini_window, 0);
248 }
249
ff11dfa1
JB
250 /* Make a frame containing just a root window. */
251 f = make_frame (0);
dc6f92b8
JB
252
253 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 254 f->minibuffer_window = mini_window;
dc6f92b8 255 Fset_window_buffer (mini_window,
265a9e55 256 (NILP (Vminibuffer_list)
dc6f92b8
JB
257 ? get_minibuffer (0)
258 : Fcar (Vminibuffer_list)));
ff11dfa1 259 return f;
dc6f92b8
JB
260}
261
ff11dfa1 262/* Make a frame containing only a minibuffer window. */
dc6f92b8 263
ff11dfa1
JB
264struct frame *
265make_minibuffer_frame ()
dc6f92b8 266{
ff11dfa1 267 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 268
ff11dfa1 269 register struct frame *f = make_frame (0);
dc6f92b8 270 register Lisp_Object mini_window;
ff11dfa1 271 register Lisp_Object frame;
dc6f92b8 272
ff11dfa1 273 XSET (frame, Lisp_Frame, f);
dc6f92b8 274
804518aa 275 f->auto_raise = 0;
ff11dfa1
JB
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;
804518aa 288 XWINDOW (mini_window)->prev = Qnil;
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 403/* Return the next frame in the frame list after FRAME.
ff11dfa1
JB
404 If MINIBUF is nil, exclude minibuffer-only frames.
405 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
406 their minibuffer.
407 If MINIBUF is non-nil, and not a window, include all frames. */
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 422 {
d06a8a56
JB
423 Lisp_Object f = XCONS (tail)->car;
424
dc6f92b8 425 if (passed)
d5e7c279 426 {
d06a8a56
JB
427 /* Decide whether this frame is eligible to be returned. */
428
429 /* If we've looped all the way around without finding any
430 eligible frames, return the original frame. */
431 if (EQ (f, frame))
432 return f;
433
434 /* Let minibuf decide if this frame is acceptable. */
435 if (NILP (minibuf))
436 {
437 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
438 return f;
439 }
440 else if (XTYPE (minibuf) == Lisp_Window)
441 {
442 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
443 return f;
444 }
445 else
ff11dfa1 446 return f;
d5e7c279 447 }
dc6f92b8 448
d06a8a56 449 if (EQ (frame, f))
dc6f92b8
JB
450 passed++;
451 }
452}
453
d06a8a56
JB
454#if 0
455/* Nobody seems to be using this code right now. */
456
ff11dfa1 457/* Return the previous frame in the frame list before FRAME.
ff11dfa1
JB
458 If MINIBUF is nil, exclude minibuffer-only frames.
459 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
460 their minibuffer.
461 If MINIBUF is non-nil and not a window, include all frames. */
dc6f92b8 462Lisp_Object
ff11dfa1
JB
463prev_frame (frame, minibuf)
464 Lisp_Object frame;
f9898cc6 465 Lisp_Object minibuf;
dc6f92b8
JB
466{
467 Lisp_Object tail;
468 Lisp_Object prev;
469
ff11dfa1
JB
470 /* There must always be at least one frame in Vframe_list. */
471 if (! CONSP (Vframe_list))
f9898cc6
JB
472 abort ();
473
dc6f92b8 474 prev = Qnil;
d06a8a56 475 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 476 {
d06a8a56 477 Lisp_Object f = XCONS (tail)->car;
f9898cc6 478
d06a8a56
JB
479 if (XTYPE (f) != Lisp_Frame)
480 abort ();
f9898cc6 481
d06a8a56
JB
482 if (EQ (frame, f) && !NILP (prev))
483 return prev;
f9898cc6 484
d06a8a56
JB
485 /* Decide whether this frame is eligible to be returned,
486 according to minibuf. */
487 if (NILP (minibuf))
488 {
489 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
490 prev = f;
f9898cc6 491 }
d06a8a56
JB
492 else if (XTYPE (minibuf) == Lisp_Window)
493 {
494 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
495 prev = f;
496 }
497 else
498 prev = f;
f9898cc6 499 }
d06a8a56
JB
500
501 /* We've scanned the entire list. */
502 if (NILP (prev))
503 /* We went through the whole frame list without finding a single
504 acceptable frame. Return the original frame. */
505 return frame;
506 else
507 /* There were no acceptable frames in the list before FRAME; otherwise,
508 we would have returned directly from the loop. Since PREV is the last
509 acceptable frame in the list, return it. */
510 return prev;
dc6f92b8 511}
d06a8a56 512#endif
dc6f92b8 513
ff11dfa1
JB
514DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
515 "Return the next frame in the frame list after FRAME.\n\
d06a8a56
JB
516If omitted, FRAME defaults to the selected frame.\n\
517If optional argument MINIBUF is nil or omitted, exclude minibuffer-only frames.\n\
518If MINIBUF is a window, include only frames using that window for their\n\
519minibuffer.\n\
520If MINIBUF is non-nil and not a window, include all frames.")
ff11dfa1
JB
521 (frame, miniframe)
522Lisp_Object frame, miniframe;
dc6f92b8
JB
523{
524 Lisp_Object tail;
525
ff11dfa1
JB
526 if (NILP (frame))
527 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 528 else
ff11dfa1 529 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 530
ff11dfa1 531 return next_frame (frame, miniframe);
dc6f92b8 532}
ff11dfa1 533#endif /* MULTI_FRAME */
dc6f92b8 534\f
ff11dfa1
JB
535DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
536 "Delete FRAME, permanently eliminating it from use.\n\
537If omitted, FRAME defaults to the selected frame.\n\
538A frame may not be deleted if its minibuffer is used by other frames.")
539 (frame)
540 Lisp_Object frame;
dc6f92b8 541{
ff11dfa1 542 struct frame *f;
dc6f92b8
JB
543 union display displ;
544
ff11dfa1 545 if (EQ (frame, Qnil))
dc6f92b8 546 {
ff11dfa1
JB
547 f = selected_frame;
548 XSET (frame, Lisp_Frame, f);
dc6f92b8
JB
549 }
550 else
551 {
ff11dfa1
JB
552 CHECK_FRAME (frame, 0);
553 f = XFRAME (frame);
dc6f92b8
JB
554 }
555
ff11dfa1 556 if (! FRAME_LIVE_P (f))
f9898cc6
JB
557 return;
558
ff11dfa1
JB
559 /* Are there any other frames besides this one? */
560 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
561 error ("Attempt to delete the only frame");
d5e7c279 562
ff11dfa1
JB
563 /* Does this frame have a minibuffer, and is it the surrogate
564 minibuffer for any other frame? */
fd0c2bd1 565 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 566 {
ff11dfa1 567 Lisp_Object frames;
1113d9db 568
ff11dfa1
JB
569 for (frames = Vframe_list;
570 CONSP (frames);
571 frames = XCONS (frames)->cdr)
1113d9db 572 {
ff11dfa1 573 Lisp_Object this = XCONS (frames)->car;
1113d9db 574
ff11dfa1
JB
575 if (! EQ (this, frame)
576 && EQ (frame,
577 (WINDOW_FRAME
1113d9db 578 (XWINDOW
ff11dfa1
JB
579 (FRAME_MINIBUF_WINDOW
580 (XFRAME (this)))))))
581 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 582 }
dc6f92b8
JB
583 }
584
ff11dfa1
JB
585 /* Don't let the frame remain selected. */
586 if (f == selected_frame)
587 Fselect_frame (next_frame (frame, Qt));
dc6f92b8 588
ff11dfa1
JB
589 /* Don't allow minibuf_window to remain on a deleted frame. */
590 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 591 {
ff11dfa1 592 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 593 XWINDOW (minibuf_window)->buffer);
ff11dfa1 594 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
595 }
596
ff11dfa1
JB
597 Vframe_list = Fdelq (frame, Vframe_list);
598 f->visible = 0;
599 displ = f->display;
600 f->display.nothing = 0;
dc6f92b8 601
d5e7c279 602#ifdef HAVE_X_WINDOWS
fd0c2bd1 603 if (FRAME_X_P (f))
ff11dfa1 604 x_destroy_window (f, displ);
d5e7c279
JB
605#endif
606
ff11dfa1 607 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 608 another one. */
ff11dfa1 609 if (f == last_nonminibuf_frame)
d5e7c279 610 {
ff11dfa1 611 Lisp_Object frames;
1113d9db 612
ff11dfa1 613 last_nonminibuf_frame = 0;
d5e7c279 614
ff11dfa1
JB
615 for (frames = Vframe_list;
616 CONSP (frames);
617 frames = XCONS (frames)->cdr)
d5e7c279 618 {
ff11dfa1
JB
619 f = XFRAME (XCONS (frames)->car);
620 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 621 {
ff11dfa1 622 last_nonminibuf_frame = f;
d5e7c279
JB
623 break;
624 }
625 }
626 }
dc6f92b8 627
ff11dfa1
JB
628 /* If we've deleted Vdefault_minibuffer_frame, try to find another
629 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 630 with other windows. */
ff11dfa1 631 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 632 {
ff11dfa1 633 Lisp_Object frames;
1113d9db 634
ff11dfa1
JB
635 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
636 Lisp_Object frame_with_minibuf = Qnil;
1113d9db 637
ff11dfa1
JB
638 for (frames = Vframe_list;
639 CONSP (frames);
640 frames = XCONS (frames)->cdr)
1113d9db 641 {
ff11dfa1 642 Lisp_Object this = XCONS (frames)->car;
1113d9db 643
ff11dfa1 644 if (XTYPE (this) != Lisp_Frame)
1113d9db 645 abort ();
ff11dfa1 646 f = XFRAME (this);
1113d9db 647
fd0c2bd1 648 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 649 {
ff11dfa1
JB
650 frame_with_minibuf = this;
651 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
652 break;
653 }
654 }
655
ff11dfa1
JB
656 /* We know that there must be some frame with a minibuffer out
657 there. If this were not true, all of the frames present
1113d9db 658 would have to be minibufferless, which implies that at some
ff11dfa1 659 point their minibuffer frames must have been deleted, but
1113d9db 660 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
661 minibuffer frames. */
662 if (NILP (frame_with_minibuf))
1113d9db
JB
663 abort ();
664
ff11dfa1 665 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
666 }
667
dc6f92b8
JB
668 return Qnil;
669}
670\f
671/* Return mouse position in character cell units. */
672
f9898cc6 673DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 674 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
f9898cc6 675If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 676to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
677and nil for X and Y.")
678 ()
dc6f92b8 679{
f9898cc6 680 Lisp_Object x, y, dummy;
ff11dfa1 681 FRAME_PTR f;
dc6f92b8 682
f9898cc6 683 if (mouse_position_hook)
ff11dfa1 684 (*mouse_position_hook) (&f, &x, &y, &dummy);
f9898cc6
JB
685 else
686 {
ff11dfa1 687 f = selected_frame;
f9898cc6
JB
688 x = y = Qnil;
689 }
dc6f92b8 690
ff11dfa1 691 XSET (dummy, Lisp_Frame, f);
f9898cc6 692 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
dc6f92b8
JB
693}
694
695DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
ff11dfa1
JB
696 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
697WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
698 (frame, x, y)
699 Lisp_Object frame, x, y;
dc6f92b8 700{
ff11dfa1 701 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
702 CHECK_NUMBER (x, 2);
703 CHECK_NUMBER (y, 1);
704
705#ifdef HAVE_X_WINDOWS
fd0c2bd1 706 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 707 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 708 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
709#endif
710
711 return Qnil;
712}
713\f
714#if 0
715/* ??? Can this be replaced with a Lisp function?
06b1a5ef
JB
716 It is used in minibuf.c. Can we get rid of that?
717 Yes. All uses in minibuf.c are gone, and parallels to these
ff11dfa1 718 functions have been defined in frame.el. */
dc6f92b8 719
ff11dfa1 720DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
dc6f92b8 721 0, 0, 0,
ff11dfa1
JB
722 "Return object describing current frame configuration.\n\
723The frame configuration is the current mouse position and selected frame.\n\
724This object can be given to `restore-frame-configuration'\n\
725to restore this frame configuration.")
dc6f92b8
JB
726 ()
727{
f9898cc6 728 Lisp_Object c, time;
dc6f92b8 729
f9898cc6 730 c = Fmake_vector (make_number(4), Qnil);
ff11dfa1 731 XVECTOR (c)->contents[0] = Fselected_frame();
f9898cc6
JB
732 if (mouse_position_hook)
733 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
734 &XVECTOR (c)->contents[2],
735 &XVECTOR (c)->contents[3],
736 &time);
dc6f92b8
JB
737 return c;
738}
739
ff11dfa1
JB
740DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
741 Srestore_frame_configuration,
dc6f92b8 742 1, 1, 0,
ff11dfa1 743 "Restores frame configuration CONFIGURATION.")
dc6f92b8
JB
744 (config)
745 Lisp_Object config;
746{
ff11dfa1 747 Lisp_Object x_pos, y_pos, frame;
dc6f92b8
JB
748
749 CHECK_VECTOR (config, 0);
750 if (XVECTOR (config)->size != 3)
751 {
ff11dfa1 752 error ("Wrong size vector passed to restore-frame-configuration");
dc6f92b8 753 }
ff11dfa1
JB
754 frame = XVECTOR (config)->contents[0];
755 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 756
ff11dfa1 757 Fselect_frame (frame, Qnil);
dc6f92b8
JB
758
759#if 0
ff11dfa1 760 /* This seems to interfere with the frame selection mechanism. jla */
f9898cc6
JB
761 x_pos = XVECTOR (config)->contents[2];
762 y_pos = XVECTOR (config)->contents[3];
ff11dfa1 763 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
dc6f92b8
JB
764#endif
765
ff11dfa1 766 return frame;
dc6f92b8
JB
767}
768#endif
769\f
ff11dfa1 770DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1aa66088 771 0, 1, 0,
ff11dfa1
JB
772 "Make the frame FRAME visible (assuming it is an X-window).\n\
773Also raises the frame so that nothing obscures it.")
774 (frame)
775 Lisp_Object frame;
dc6f92b8 776{
1aa66088 777 if (NILP (frame))
7500877e 778 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 779
ff11dfa1 780 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 781
fd0c2bd1
JB
782#ifdef HAVE_X_WINDOWS
783 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 784 x_make_frame_visible (XFRAME (frame));
fd0c2bd1 785#endif
dc6f92b8 786
ff11dfa1 787 return frame;
dc6f92b8
JB
788}
789
ff11dfa1 790DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1aa66088 791 0, 1, "",
ff11dfa1
JB
792 "Make the frame FRAME invisible (assuming it is an X-window).")
793 (frame)
794 Lisp_Object frame;
dc6f92b8 795{
1aa66088 796 if (NILP (frame))
7500877e 797 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 798
ff11dfa1 799 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 800
fd0c2bd1
JB
801#ifdef HAVE_X_WINDOWS
802 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 803 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 804#endif
dc6f92b8
JB
805
806 return Qnil;
807}
808
ff11dfa1 809DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 810 0, 1, "",
ff11dfa1
JB
811 "Make the frame FRAME into an icon.")
812 (frame)
813 Lisp_Object frame;
dc6f92b8 814{
1aa66088 815 if (NILP (frame))
7500877e 816 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 817
ff11dfa1 818 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 819
fd0c2bd1
JB
820#ifdef HAVE_X_WINDOWS
821 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 822 x_iconify_frame (XFRAME (frame));
fd0c2bd1 823#endif
dc6f92b8
JB
824
825 return Qnil;
826}
827
ff11dfa1 828DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 829 1, 1, 0,
ff11dfa1
JB
830 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
831A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 832a window system, it may not show at all.\n\
fd0c2bd1 833Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
834 (frame)
835 Lisp_Object frame;
dc6f92b8 836{
ff11dfa1 837 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 838
ff11dfa1 839 if (XFRAME (frame)->visible)
dc6f92b8 840 return Qt;
ff11dfa1 841 if (XFRAME (frame)->iconified)
fd0c2bd1 842 return Qicon;
dc6f92b8
JB
843 return Qnil;
844}
845
ff11dfa1 846DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 847 0, 0, 0,
ff11dfa1 848 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
849 ()
850{
ff11dfa1
JB
851 Lisp_Object tail, frame;
852 struct frame *f;
dc6f92b8
JB
853 Lisp_Object value;
854
855 value = Qnil;
ff11dfa1 856 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 857 {
ff11dfa1
JB
858 frame = XCONS (tail)->car;
859 if (XTYPE (frame) != Lisp_Frame)
dc6f92b8 860 continue;
ff11dfa1
JB
861 f = XFRAME (frame);
862 if (f->visible)
863 value = Fcons (frame, value);
dc6f92b8
JB
864 }
865 return value;
866}
d5e7c279
JB
867
868
869\f
ff11dfa1 870DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 871 1, 2, 0,
ff11dfa1
JB
872 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
873This means that, after reading a keystroke typed at FRAME,\n\
874`last-event-frame' will be FOCUS-FRAME.\n\
d5e7c279 875\n\
ff11dfa1
JB
876If FOCUS-FRAME is omitted or eq to FRAME, any existing redirection is\n\
877cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 878\n\
ff11dfa1
JB
879The redirection lasts until the next call to `redirect-frame-focus'\n\
880or `select-frame'.\n\
d5e7c279
JB
881\n\
882This is useful for temporarily redirecting keystrokes to the minibuffer\n\
ff11dfa1
JB
883window when a frame doesn't have its own minibuffer.")
884 (frame, focus_frame)
885 Lisp_Object frame, focus_frame;
d5e7c279 886{
ff11dfa1 887 CHECK_LIVE_FRAME (frame, 0);
f9898cc6 888
ff11dfa1
JB
889 if (NILP (focus_frame))
890 focus_frame = frame;
d5e7c279 891 else
ff11dfa1 892 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 893
ff11dfa1 894 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 895
ff11dfa1
JB
896 if (frame_rehighlight_hook)
897 (*frame_rehighlight_hook) ();
d5e7c279
JB
898
899 return Qnil;
900}
901
902
ff11dfa1
JB
903DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
904 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
905See `redirect-frame-focus'.")
906 (frame)
907 Lisp_Object frame;
d5e7c279 908{
ff11dfa1
JB
909 CHECK_LIVE_FRAME (frame, 0);
910 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
911}
912
913
dc6f92b8
JB
914\f
915Lisp_Object
ff11dfa1
JB
916get_frame_param (frame, prop)
917 register struct frame *frame;
dc6f92b8
JB
918 Lisp_Object prop;
919{
920 register Lisp_Object tem;
921
ff11dfa1 922 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
923 if (EQ (tem, Qnil))
924 return tem;
925 return Fcdr (tem);
926}
927
928void
fd0c2bd1 929store_in_alist (alistptr, prop, val)
dc6f92b8 930 Lisp_Object *alistptr, val;
fd0c2bd1 931 Lisp_Object prop;
dc6f92b8
JB
932{
933 register Lisp_Object tem;
dc6f92b8 934
dc6f92b8
JB
935 tem = Fassq (prop, *alistptr);
936 if (EQ (tem, Qnil))
937 *alistptr = Fcons (Fcons (prop, val), *alistptr);
938 else
939 Fsetcdr (tem, val);
940}
941
942void
ff11dfa1
JB
943store_frame_param (f, prop, val)
944 struct frame *f;
dc6f92b8
JB
945 Lisp_Object prop, val;
946{
947 register Lisp_Object tem;
948
ff11dfa1 949 tem = Fassq (prop, f->param_alist);
dc6f92b8 950 if (EQ (tem, Qnil))
ff11dfa1 951 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
952 else
953 Fsetcdr (tem, val);
bc93c097
JB
954
955 if (EQ (prop, Qminibuffer)
956 && XTYPE (val) == Lisp_Window)
957 {
958 if (! MINI_WINDOW_P (XWINDOW (val)))
959 error ("Surrogate minibuffer windows must be minibuffer windows.");
960
fd0c2bd1 961 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
ff11dfa1 962 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
bc93c097
JB
963
964 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 965 f->minibuffer_window = val;
bc93c097 966 }
dc6f92b8
JB
967}
968
ff11dfa1
JB
969DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
970 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 971It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
972The meaningful PARMs depend on the kind of frame.\n\
973If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
974 (frame)
975 Lisp_Object frame;
dc6f92b8
JB
976{
977 Lisp_Object alist;
ff11dfa1 978 struct frame *f;
dc6f92b8 979
ff11dfa1
JB
980 if (EQ (frame, Qnil))
981 f = selected_frame;
dc6f92b8
JB
982 else
983 {
ff11dfa1
JB
984 CHECK_FRAME (frame, 0);
985 f = XFRAME (frame);
dc6f92b8
JB
986 }
987
ff11dfa1 988 if (f->display.nothing == 0)
dc6f92b8
JB
989 return Qnil;
990
ff11dfa1 991 alist = Fcopy_alist (f->param_alist);
fd0c2bd1
JB
992 store_in_alist (&alist, Qname, f->name);
993 store_in_alist (&alist, Qheight, make_number (f->height));
994 store_in_alist (&alist, Qwidth, make_number (f->width));
995 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
996 store_in_alist (&alist, Qminibuffer,
997 (! FRAME_HAS_MINIBUF_P (f) ? Qnone
998 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
999 : FRAME_MINIBUF_WINDOW (f))));
1000 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1001
1002#ifdef HAVE_X_WINDOWS
1003 if (FRAME_X_P (f))
ff11dfa1 1004 x_report_frame_params (f, &alist);
fd0c2bd1 1005#endif
dc6f92b8
JB
1006 return alist;
1007}
1008
ff11dfa1
JB
1009DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1010 Smodify_frame_parameters, 2, 2, 0,
1011 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1012ALIST is an alist of parameters to change and their new values.\n\
1013Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1014The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1015 (frame, alist)
1016 Lisp_Object frame, alist;
dc6f92b8 1017{
fd0c2bd1 1018 FRAME_PTR f;
dc6f92b8
JB
1019 register Lisp_Object tail, elt, prop, val;
1020
ff11dfa1
JB
1021 if (EQ (frame, Qnil))
1022 f = selected_frame;
dc6f92b8
JB
1023 else
1024 {
ff11dfa1
JB
1025 CHECK_LIVE_FRAME (frame, 0);
1026 f = XFRAME (frame);
dc6f92b8
JB
1027 }
1028
fd0c2bd1
JB
1029#ifdef HAVE_X_WINDOWS
1030 if (FRAME_X_P (f))
1031#if 1
1032 x_set_frame_parameters (f, alist);
1033#else
dc6f92b8
JB
1034 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1035 {
1036 elt = Fcar (tail);
1037 prop = Fcar (elt);
1038 val = Fcdr (elt);
fd0c2bd1 1039 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
ff11dfa1 1040 store_frame_param (f, prop, val);
dc6f92b8 1041 }
fd0c2bd1
JB
1042#endif
1043#endif
dc6f92b8
JB
1044
1045 return Qnil;
1046}
1047\f
1048
dc6d9681
JB
1049#if 0
1050/* This function isn't useful enough by itself to include; we need to
1051 add functions to allow the user to find the size of a font before
1052 this is actually useful. */
1053
ff11dfa1
JB
1054DEFUN ("frame-pixel-size", Fframe_pixel_size,
1055 Sframe_pixel_size, 1, 1, 0,
1056 "Return a cons (width . height) of FRAME's size in pixels.")
1057 (frame)
1058 Lisp_Object frame;
dc6f92b8 1059{
ff11dfa1 1060 register struct frame *f;
dc6f92b8
JB
1061 int width, height;
1062
ff11dfa1
JB
1063 CHECK_LIVE_FRAME (frame, 0);
1064 f = XFRAME (frame);
dc6f92b8 1065
ff11dfa1
JB
1066 return Fcons (make_number (x_pixel_width (f)),
1067 make_number (x_pixel_height (f)));
dc6f92b8 1068}
dc6d9681
JB
1069#endif
1070
1071#if 0
1072/* These functions have no C callers, and can be written nicely in lisp. */
dc6f92b8 1073
ff11dfa1
JB
1074DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1075 "Return number of lines available for display on selected frame.")
dc6f92b8
JB
1076 ()
1077{
ff11dfa1 1078 return make_number (FRAME_HEIGHT (selected_frame));
dc6f92b8
JB
1079}
1080
ff11dfa1
JB
1081DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1082 "Return number of columns available for display on selected frame.")
dc6f92b8
JB
1083 ()
1084{
ff11dfa1 1085 return make_number (FRAME_WIDTH (selected_frame));
dc6f92b8 1086}
dc6d9681 1087#endif
dc6f92b8 1088
ff11dfa1
JB
1089DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1090 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1091Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1092but that the idea of the actual height of the frame should not be changed.")
1093 (frame, rows, pretend)
fd0c2bd1 1094 Lisp_Object frame, rows, pretend;
dc6f92b8 1095{
ff11dfa1 1096 register struct frame *f;
dc6f92b8
JB
1097
1098 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1099 if (NILP (frame))
1100 f = selected_frame;
dc6f92b8
JB
1101 else
1102 {
ff11dfa1
JB
1103 CHECK_LIVE_FRAME (frame, 0);
1104 f = XFRAME (frame);
dc6f92b8
JB
1105 }
1106
fd0c2bd1
JB
1107#ifdef HAVE_X_WINDOWS
1108 if (FRAME_X_P (f))
dc6f92b8 1109 {
ff11dfa1
JB
1110 if (XINT (rows) != f->width)
1111 x_set_window_size (f, f->width, XINT (rows));
dc6f92b8
JB
1112 }
1113 else
fd0c2bd1
JB
1114#endif
1115 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1116 return Qnil;
1117}
1118
ff11dfa1
JB
1119DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1120 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1121Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1122but that the idea of the actual width of the frame should not be changed.")
1123 (frame, cols, pretend)
fd0c2bd1 1124 Lisp_Object frame, cols, pretend;
dc6f92b8 1125{
ff11dfa1 1126 register struct frame *f;
dc6f92b8 1127 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1128 if (NILP (frame))
1129 f = selected_frame;
dc6f92b8
JB
1130 else
1131 {
ff11dfa1
JB
1132 CHECK_LIVE_FRAME (frame, 0);
1133 f = XFRAME (frame);
dc6f92b8
JB
1134 }
1135
fd0c2bd1
JB
1136#ifdef HAVE_X_WINDOWS
1137 if (FRAME_X_P (f))
dc6f92b8 1138 {
ff11dfa1
JB
1139 if (XINT (cols) != f->width)
1140 x_set_window_size (f, XINT (cols), f->height);
dc6f92b8
JB
1141 }
1142 else
fd0c2bd1
JB
1143#endif
1144 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1145 return Qnil;
1146}
1147
ff11dfa1
JB
1148DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1149 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1150 (frame, cols, rows)
1151 Lisp_Object frame, cols, rows;
dc6f92b8 1152{
ff11dfa1 1153 register struct frame *f;
dc6f92b8
JB
1154 int mask;
1155
ff11dfa1 1156 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1157 CHECK_NUMBER (cols, 2);
1158 CHECK_NUMBER (rows, 1);
ff11dfa1 1159 f = XFRAME (frame);
dc6f92b8 1160
fd0c2bd1
JB
1161#ifdef HAVE_X_WINDOWS
1162 if (FRAME_X_P (f))
dc6f92b8 1163 {
ff11dfa1
JB
1164 if (XINT (rows) != f->height || XINT (cols) != f->width)
1165 x_set_window_size (f, XINT (cols), XINT (rows));
dc6f92b8
JB
1166 }
1167 else
fd0c2bd1
JB
1168#endif
1169 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1170
1171 return Qnil;
1172}
1173
ff11dfa1
JB
1174DEFUN ("set-frame-position", Fset_frame_position,
1175 Sset_frame_position, 3, 3, 0,
1176 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
f9898cc6 1177If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
ff11dfa1 1178the leftmost or bottommost position FRAME could occupy without going\n\
fd0c2bd1 1179off the screen.")
ff11dfa1
JB
1180 (frame, xoffset, yoffset)
1181 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1182{
ff11dfa1 1183 register struct frame *f;
dc6f92b8
JB
1184 int mask;
1185
ff11dfa1 1186 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1187 CHECK_NUMBER (xoffset, 1);
1188 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1189 f = XFRAME (frame);
dc6f92b8 1190
fd0c2bd1
JB
1191#ifdef HAVE_X_WINDOWS
1192 if (FRAME_X_P (f))
ff11dfa1 1193 x_set_offset (f, XINT (xoffset), XINT (yoffset));
fd0c2bd1 1194#endif
dc6f92b8
JB
1195
1196 return Qt;
1197}
dc6d9681 1198
dc6f92b8 1199\f
dc6f92b8
JB
1200#ifndef HAVE_X11
1201DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1202 3, 3, "",
ff11dfa1
JB
1203 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1204Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
dc6f92b8
JB
1205the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1206specify defaults for some sizes/positions. If GEO specifies everything,\n\
1207the mouse is not used.\n\
ff11dfa1
JB
1208Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1209 (frame, name, geo)
1210 Lisp_Object frame;
dc6f92b8
JB
1211 Lisp_Object name;
1212 Lisp_Object geo;
1213{
1214 int vals[4];
1215 Lisp_Object nums[4];
1216 int i;
1217
ff11dfa1 1218 CHECK_FRAME (frame, 0);
dc6f92b8
JB
1219 CHECK_STRING (name, 1);
1220 CHECK_STRING (geo, 2);
1221
ff11dfa1 1222 switch (XFRAME (frame)->output_method)
dc6f92b8
JB
1223 {
1224 case output_x_window:
ff11dfa1 1225 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
dc6f92b8
JB
1226 XSTRING (geo)->data, XSTRING (name)->data);
1227 break;
1228
1229 default:
1230 return Qnil;
1231 }
1232
1233 for (i = 0; i < 4; i++)
1234 XFASTINT (nums[i]) = vals[i];
ff11dfa1 1235 return Fcons (frame, Flist (4, nums));
dc6f92b8
JB
1236 return Qnil;
1237}
1238#endif /* not HAVE_X11 */
1239\f
ff11dfa1 1240choose_minibuf_frame ()
dc6f92b8 1241{
ff11dfa1
JB
1242 /* For lowest-level minibuf, put it on currently selected frame
1243 if frame has a minibuffer. */
d06a8a56 1244
dc6f92b8 1245 if (minibuf_level == 0
ff11dfa1 1246 && selected_frame != 0
d06a8a56 1247 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1248 {
d06a8a56
JB
1249 /* I don't think that any frames may validly have a null minibuffer
1250 window anymore. */
1251 if (NILP (selected_frame->minibuffer_window))
1252 abort ();
1253
ff11dfa1 1254 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1255 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1256 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1257 }
1258}
1259\f
ff11dfa1 1260syms_of_frame ()
dc6f92b8 1261{
fd0c2bd1 1262 /*&&& init symbols here &&&*/
ff11dfa1 1263 Qframep = intern ("framep");
ff11dfa1 1264 staticpro (&Qframep);
fd0c2bd1 1265 Qlive_frame_p = intern ("live-frame-p");
ff11dfa1 1266 staticpro (&Qlive_frame_p);
fd0c2bd1
JB
1267 Qheight = intern ("height");
1268 staticpro (&Qheight);
1269 Qicon = intern ("icon");
1270 staticpro (&Qicon);
1271 Qminibuffer = intern ("minibuffer");
bc93c097 1272 staticpro (&Qminibuffer);
fd0c2bd1
JB
1273 Qmodeline = intern ("modeline");
1274 staticpro (&Qmodeline);
1275 Qname = intern ("name");
1276 staticpro (&Qname);
1277 Qnone = intern ("none");
1278 staticpro (&Qnone);
1279 Qonly = intern ("only");
1280 staticpro (&Qonly);
1281 Qunsplittable = intern ("unsplittable");
1282 staticpro (&Qunsplittable);
1283 Qwidth = intern ("width");
1284 staticpro (&Qwidth);
1285 Qx = intern ("x");
1286 staticpro (&Qx);
dc6f92b8 1287
ff11dfa1 1288 staticpro (&Vframe_list);
dc6f92b8 1289
ff11dfa1
JB
1290 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1291 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1292
1293 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1294 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1295 Vemacs_iconified = Qnil;
1296
ff11dfa1
JB
1297 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1298 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1299\n\
ff11dfa1 1300Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1301appropriate surrogate.\n\
1302\n\
1303Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1304frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1305minibuffer, no matter what this variable is set to. This means that\n\
1306this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1307current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1308displayed.");
ff11dfa1 1309 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1310
ff11dfa1
JB
1311 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1312 "Alist of default values for frame creation.\n\
5bce042c 1313These may be set in your init file, like this:\n\
ff11dfa1 1314 (setq default-frame-alist '((width . 80) (height . 55)))\n\
5bce042c
JB
1315These override values given in window system configuration data, like\n\
1316X Windows' defaults database.\n\
ff11dfa1
JB
1317For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1318For values specific to the separate minibuffer frame, see\n\
1319`minibuffer-frame-alist'.");
1320 Vdefault_frame_alist = Qnil;
1321
1322 defsubr (&Sframep);
1323 defsubr (&Slive_frame_p);
1324 defsubr (&Sselect_frame);
1325 defsubr (&Sselected_frame);
1326 defsubr (&Swindow_frame);
1327 defsubr (&Sframe_root_window);
1328 defsubr (&Sframe_selected_window);
1329 defsubr (&Sframe_list);
1330 defsubr (&Snext_frame);
1331 defsubr (&Sdelete_frame);
f9898cc6 1332 defsubr (&Smouse_position);
dc6f92b8
JB
1333 defsubr (&Sset_mouse_position);
1334#if 0
ff11dfa1
JB
1335 defsubr (&Sframe_configuration);
1336 defsubr (&Srestore_frame_configuration);
dc6f92b8 1337#endif
ff11dfa1
JB
1338 defsubr (&Smake_frame_visible);
1339 defsubr (&Smake_frame_invisible);
1340 defsubr (&Siconify_frame);
1341 defsubr (&Sframe_visible_p);
1342 defsubr (&Svisible_frame_list);
1343 defsubr (&Sredirect_frame_focus);
1344 defsubr (&Sframe_focus);
1345 defsubr (&Sframe_parameters);
1346 defsubr (&Smodify_frame_parameters);
1265558a 1347#if 0
ff11dfa1
JB
1348 defsubr (&Sframe_pixel_size);
1349 defsubr (&Sframe_height);
1350 defsubr (&Sframe_width);
1265558a 1351#endif
ff11dfa1
JB
1352 defsubr (&Sset_frame_height);
1353 defsubr (&Sset_frame_width);
1354 defsubr (&Sset_frame_size);
1355 defsubr (&Sset_frame_position);
dc6f92b8
JB
1356#ifndef HAVE_X11
1357 defsubr (&Srubber_band_rectangle);
1358#endif /* HAVE_X11 */
1359}
e5d77022 1360
d06a8a56 1361#else /* not MULTI_FRAME */
fd0c2bd1 1362
cc38027b
JB
1363/* If we're not using multi-frame stuff, we still need to provide some
1364 support functions. */
1365
1366/* Unless this function is defined, providing set-frame-height and
1367 set-frame-width doesn't help compatibility any, since they both
1368 want this as their first argument. */
1369DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1370 "Return the frame that is now selected.")
1371 ()
1372{
1373 Lisp_Object tem;
1374 XFASTINT (tem) = 0;
1375 return tem;
1376}
fd0c2bd1
JB
1377
1378DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1379 "Specify that the frame FRAME has LINES lines.\n\
1380Optional third arg non-nil means that redisplay should use LINES lines\n\
1381but that the idea of the actual height of the frame should not be changed.")
1382 (frame, rows, pretend)
1383 Lisp_Object frame, rows, pretend;
1384{
1385 CHECK_NUMBER (rows, 0);
1386
1387 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1388 return Qnil;
1389}
1390
1391DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1392 "Specify that the frame FRAME has COLS columns.\n\
1393Optional third arg non-nil means that redisplay should use COLS columns\n\
1394but that the idea of the actual width of the frame should not be changed.")
1395 (frame, cols, pretend)
1396 Lisp_Object frame, cols, pretend;
1397{
1398 CHECK_NUMBER (cols, 0);
1399
1400 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1401 return Qnil;
1402}
1403
1404DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1405 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1406 (frame, cols, rows)
1407 Lisp_Object frame, cols, rows;
1408{
1409 CHECK_NUMBER (cols, 2);
1410 CHECK_NUMBER (rows, 1);
1411
1412 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1413
1414 return Qnil;
1415}
1416
cc38027b
JB
1417DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1418 "Return number of lines available for display on selected frame.")
1419 ()
1420{
1421 return make_number (FRAME_HEIGHT (selected_frame));
1422}
1423
1424DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1425 "Return number of columns available for display on selected frame.")
1426 ()
1427{
1428 return make_number (FRAME_WIDTH (selected_frame));
1429}
1430
1431/* These are for backward compatibility with Emacs 18. */
1432
fd0c2bd1
JB
1433DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1434 "Tell redisplay that the screen has LINES lines.\n\
1435Optional second arg non-nil means that redisplay should use LINES lines\n\
1436but that the idea of the actual height of the screen should not be changed.")
1437 (lines, pretend)
1438 Lisp_Object lines, pretend;
1439{
1440 CHECK_NUMBER (lines, 0);
1441
1442 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1443 return Qnil;
1444}
1445
1446DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1447 "Tell redisplay that the screen has COLS columns.\n\
1448Optional second arg non-nil means that redisplay should use COLS columns\n\
1449but that the idea of the actual width of the screen should not be changed.")
1450 (cols, pretend)
1451 Lisp_Object cols, pretend;
1452{
1453 CHECK_NUMBER (cols, 0);
1454
1455 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1456 return Qnil;
1457}
1458
fd0c2bd1
JB
1459syms_of_frame ()
1460{
1461 defsubr (&Sset_frame_height);
1462 defsubr (&Sset_frame_width);
1463 defsubr (&Sset_frame_size);
1464 defsubr (&Sset_screen_height);
1465 defsubr (&Sset_screen_width);
1466 defsubr (&Sframe_height);
1467 Ffset (intern ("screen-height"), intern ("frame-height"));
1468 defsubr (&Sframe_width);
1469 Ffset (intern ("screen-width"), intern ("frame-width"));
1470}
1471
1472#endif /* not MULTI_FRAME */
1473
1474
1475
1476