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