*** empty log message ***
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
7c299e7a 2 Copyright (C) 1989, 1992, 1993 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
bff19c8d 28#include "buffer.h"
dc6f92b8 29#include "window.h"
d5e7c279 30#include "termhooks.h"
dc6f92b8 31
2f0b07e0
JB
32/* These help us bind and responding to switch-frame events. */
33#include "commands.h"
34#include "keyboard.h"
35
dc6f92b8 36Lisp_Object Vemacs_iconified;
ff11dfa1
JB
37Lisp_Object Vframe_list;
38Lisp_Object Vterminal_frame;
39Lisp_Object Vdefault_minibuffer_frame;
40Lisp_Object Vdefault_frame_alist;
fd0c2bd1
JB
41
42/* Evaluate this expression to rebuild the section of syms_of_frame
43 that initializes and staticpros the symbols declared below. Note
44 that Emacs 18 has a bug that keeps C-x C-e from being able to
45 evaluate this expression.
46
47(progn
48 ;; Accumulate a list of the symbols we want to initialize from the
49 ;; declarations at the top of the file.
50 (goto-char (point-min))
51 (search-forward "/\*&&& symbols declared here &&&*\/\n")
52 (let (symbol-list)
53 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
54 (setq symbol-list
55 (cons (buffer-substring (match-beginning 1) (match-end 1))
56 symbol-list))
57 (forward-line 1))
58 (setq symbol-list (nreverse symbol-list))
59 ;; Delete the section of syms_of_... where we initialize the symbols.
60 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
61 (let ((start (point)))
62 (while (looking-at "^ Q")
63 (forward-line 2))
64 (kill-region start (point)))
65 ;; Write a new symbol initialization section.
66 (while symbol-list
67 (insert (format " %s = intern (\"" (car symbol-list)))
68 (let ((start (point)))
69 (insert (substring (car symbol-list) 1))
70 (subst-char-in-region start (point) ?_ ?-))
71 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
72 (setq symbol-list (cdr symbol-list)))))
73 */
74
75/*&&& symbols declared here &&&*/
76Lisp_Object Qframep;
dbc4e1c1 77Lisp_Object Qframe_live_p;
fd0c2bd1
JB
78Lisp_Object Qheight;
79Lisp_Object Qicon;
bc93c097 80Lisp_Object Qminibuffer;
fd0c2bd1
JB
81Lisp_Object Qmodeline;
82Lisp_Object Qname;
fd0c2bd1
JB
83Lisp_Object Qonly;
84Lisp_Object Qunsplittable;
fa8fdbf9 85Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
86Lisp_Object Qwidth;
87Lisp_Object Qx;
dc6f92b8
JB
88
89extern Lisp_Object Vminibuffer_list;
90extern Lisp_Object get_minibuffer ();
91\f
ff11dfa1
JB
92DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
93 "Return non-nil if OBJECT is a frame.\n\
94Value is t for a termcap frame (a character-only terminal),\n\
95`x' for an Emacs frame that is really an X window.\n\
96Also see `live-frame-p'.")
f9898cc6
JB
97 (object)
98 Lisp_Object object;
dc6f92b8 99{
ff11dfa1 100 if (XTYPE (object) != Lisp_Frame)
dc6f92b8 101 return Qnil;
ff11dfa1 102 switch (XFRAME (object)->output_method)
dc6f92b8
JB
103 {
104 case output_termcap:
105 return Qt;
106 case output_x_window:
fd0c2bd1 107 return Qx;
dc6f92b8
JB
108 default:
109 abort ();
110 }
111}
112
dbc4e1c1 113DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
114 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
115Value is nil if OBJECT is not a live frame. If object is a live\n\
116frame, the return value indicates what sort of output device it is\n\
117displayed on. Value is t for a termcap frame (a character-only\n\
118terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
119 (object)
120 Lisp_Object object;
121{
ff11dfa1
JB
122 return ((FRAMEP (object)
123 && FRAME_LIVE_P (XFRAME (object)))
124 ? Fframep (object)
f9898cc6
JB
125 : Qnil);
126}
127
ff11dfa1
JB
128struct frame *
129make_frame (mini_p)
dc6f92b8
JB
130 int mini_p;
131{
ff11dfa1
JB
132 Lisp_Object frame;
133 register struct frame *f;
dc6f92b8
JB
134 register Lisp_Object root_window;
135 register Lisp_Object mini_window;
136
ff11dfa1 137 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
d5e7c279
JB
138 - sizeof (Lisp_Object)))
139 / sizeof (Lisp_Object)),
dc6f92b8 140 make_number (0));
ff11dfa1
JB
141 XSETTYPE (frame, Lisp_Frame);
142 f = XFRAME (frame);
143
144 f->cursor_x = 0;
145 f->cursor_y = 0;
146 f->current_glyphs = 0;
147 f->desired_glyphs = 0;
148 f->visible = 0;
323405de 149 f->async_visible = 0;
ff11dfa1
JB
150 f->display.nothing = 0;
151 f->iconified = 0;
323405de 152 f->async_iconified = 0;
ff11dfa1
JB
153 f->wants_modeline = 1;
154 f->auto_raise = 0;
155 f->auto_lower = 0;
156 f->no_split = 0;
157 f->garbaged = 0;
158 f->has_minibuffer = mini_p;
a42e9724 159 f->focus_frame = Qnil;
804518aa 160 f->explicit_name = 0;
fd2777e0
JB
161 f->can_have_scroll_bars = 0;
162 f->has_vertical_scroll_bars = 0;
ff11dfa1 163 f->param_alist = Qnil;
fd2777e0
JB
164 f->scroll_bars = Qnil;
165 f->condemned_scroll_bars = Qnil;
dc6f92b8 166
cc38027b 167 root_window = make_window ();
dc6f92b8
JB
168 if (mini_p)
169 {
cc38027b 170 mini_window = make_window ();
dc6f92b8
JB
171 XWINDOW (root_window)->next = mini_window;
172 XWINDOW (mini_window)->prev = root_window;
173 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
174 XWINDOW (mini_window)->frame = frame;
175 f->minibuffer_window = mini_window;
dc6f92b8
JB
176 }
177 else
178 {
179 mini_window = Qnil;
180 XWINDOW (root_window)->next = Qnil;
ff11dfa1 181 f->minibuffer_window = Qnil;
dc6f92b8
JB
182 }
183
ff11dfa1 184 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
185
186 /* 10 is arbitrary,
187 just so that there is "something there."
ff11dfa1 188 Correct size will be set up later with change_frame_size. */
dc6f92b8 189
ff11dfa1
JB
190 f->width = 10;
191 f->height = 10;
dc6f92b8
JB
192
193 XFASTINT (XWINDOW (root_window)->width) = 10;
194 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
195
196 if (mini_p)
197 {
198 XFASTINT (XWINDOW (mini_window)->width) = 10;
199 XFASTINT (XWINDOW (mini_window)->top) = 9;
200 XFASTINT (XWINDOW (mini_window)->height) = 1;
201 }
202
ff11dfa1 203 /* Choose a buffer for the frame's root window. */
5bce042c
JB
204 {
205 Lisp_Object buf;
206
207 XWINDOW (root_window)->buffer = Qt;
208 buf = Fcurrent_buffer ();
209 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
210 a space), try to find another one. */
211 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 212 buf = Fother_buffer (buf, Qnil);
5bce042c
JB
213 Fset_window_buffer (root_window, buf);
214 }
215
dc6f92b8
JB
216 if (mini_p)
217 {
218 XWINDOW (mini_window)->buffer = Qt;
219 Fset_window_buffer (mini_window,
265a9e55 220 (NILP (Vminibuffer_list)
dc6f92b8
JB
221 ? get_minibuffer (0)
222 : Fcar (Vminibuffer_list)));
223 }
224
ff11dfa1
JB
225 f->root_window = root_window;
226 f->selected_window = root_window;
d5e7c279
JB
227 /* Make sure this window seems more recently used than
228 a newly-created, never-selected window. */
ff11dfa1 229 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
dc6f92b8 230
ff11dfa1 231 Vframe_list = Fcons (frame, Vframe_list);
dc6f92b8 232
ff11dfa1 233 return f;
dc6f92b8
JB
234}
235\f
ff11dfa1 236/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
237 MINI_WINDOW is the minibuffer window to use. nil means use the
238 default (the global minibuffer). */
239
ff11dfa1
JB
240struct frame *
241make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
242 register Lisp_Object mini_window;
243{
ff11dfa1 244 register struct frame *f;
dc6f92b8
JB
245
246 /* Choose the minibuffer window to use. */
265a9e55 247 if (NILP (mini_window))
dc6f92b8 248 {
ff11dfa1
JB
249 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
250 error ("default-minibuffer-frame must be set when creating minibufferless frames");
251 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
252 error ("default-minibuffer-frame must be a live frame");
253 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
254 }
255 else
256 {
774910eb 257 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8
JB
258 }
259
ff11dfa1
JB
260 /* Make a frame containing just a root window. */
261 f = make_frame (0);
dc6f92b8
JB
262
263 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 264 f->minibuffer_window = mini_window;
dc6f92b8 265 Fset_window_buffer (mini_window,
265a9e55 266 (NILP (Vminibuffer_list)
dc6f92b8
JB
267 ? get_minibuffer (0)
268 : Fcar (Vminibuffer_list)));
ff11dfa1 269 return f;
dc6f92b8
JB
270}
271
ff11dfa1 272/* Make a frame containing only a minibuffer window. */
dc6f92b8 273
ff11dfa1
JB
274struct frame *
275make_minibuffer_frame ()
dc6f92b8 276{
ff11dfa1 277 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 278
ff11dfa1 279 register struct frame *f = make_frame (0);
dc6f92b8 280 register Lisp_Object mini_window;
ff11dfa1 281 register Lisp_Object frame;
dc6f92b8 282
ff11dfa1 283 XSET (frame, Lisp_Frame, f);
dc6f92b8 284
804518aa 285 f->auto_raise = 0;
ff11dfa1
JB
286 f->auto_lower = 0;
287 f->no_split = 1;
288 f->wants_modeline = 0;
289 f->has_minibuffer = 1;
dc6f92b8
JB
290
291 /* Now label the root window as also being the minibuffer.
292 Avoid infinite looping on the window chain by marking next pointer
293 as nil. */
294
ff11dfa1 295 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
296 XWINDOW (mini_window)->mini_p = Qt;
297 XWINDOW (mini_window)->next = Qnil;
804518aa 298 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 299 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
300
301 /* Put the proper buffer in that window. */
302
303 Fset_window_buffer (mini_window,
265a9e55 304 (NILP (Vminibuffer_list)
dc6f92b8
JB
305 ? get_minibuffer (0)
306 : Fcar (Vminibuffer_list)));
ff11dfa1 307 return f;
dc6f92b8
JB
308}
309\f
ff11dfa1 310/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 311
ff11dfa1
JB
312struct frame *
313make_terminal_frame ()
dc6f92b8 314{
ff11dfa1
JB
315 register struct frame *f;
316
317 Vframe_list = Qnil;
318 f = make_frame (1);
319 f->name = build_string ("terminal");
a42e9724 320 FRAME_SET_VISIBLE (f, 1);
ff11dfa1
JB
321 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
322 XSET (Vterminal_frame, Lisp_Frame, f);
323 return f;
dc6f92b8
JB
324}
325\f
2f0b07e0 326DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
8693ca83 327 "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
d5e7c279 328selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
2f0b07e0
JB
329focus on that frame.\n\
330\n\
331This function is interactive, and may be bound to the ``switch-frame''\n\
332event; when invoked this way, it switches to the frame named in the\n\
333event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
a42e9724
JB
334if it is, select the frame named in the event.\n\
335\n\
336Changing the selected frame can change focus redirections. See\n\
337`redirect-frame-focus' for details.")
ff11dfa1
JB
338 (frame, no_enter)
339 Lisp_Object frame, no_enter;
dc6f92b8 340{
2f0b07e0
JB
341 /* If FRAME is a switch-frame event, extract the frame we should
342 switch to. */
343 if (CONSP (frame)
344 && EQ (XCONS (frame)->car, Qswitch_frame)
345 && CONSP (XCONS (frame)->cdr))
346 frame = XCONS (XCONS (frame)->cdr)->car;
347
ff11dfa1 348 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 349
ff11dfa1
JB
350 if (selected_frame == XFRAME (frame))
351 return frame;
dc6f92b8 352
a42e9724
JB
353 /* If a frame's focus has been redirected toward the currently
354 selected frame, we should change the redirection to point to the
355 newly selected frame. This means that if the focus is redirected
356 from a minibufferless frame to a surrogate minibuffer frame, we
357 can use `other-window' to switch between all the frames using
358 that minibuffer frame, and the focus redirection will follow us
359 around. */
360 {
361 Lisp_Object tail;
362
363 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
364 {
365 Lisp_Object focus;
366
367 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
368 abort ();
369
370 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
371
372 if (XTYPE (focus) == Lisp_Frame
373 && XFRAME (focus) == selected_frame)
374 Fredirect_frame_focus (XCONS (tail)->car, frame);
375 }
376 }
377
ff11dfa1
JB
378 selected_frame = XFRAME (frame);
379 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
380 last_nonminibuf_frame = selected_frame;
d5e7c279 381
ff11dfa1 382 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8 383
dbc4e1c1 384 /* I think this should be done with a hook. */
dc6f92b8 385#ifdef HAVE_X_WINDOWS
fd0c2bd1 386 if (FRAME_X_P (XFRAME (frame))
265a9e55 387 && NILP (no_enter))
dc6f92b8 388 {
ff11dfa1 389 Ffocus_frame (frame);
dc6f92b8 390 }
dc6f92b8 391#endif
ff11dfa1 392 choose_minibuf_frame ();
dc6f92b8 393
074577b8
JB
394 /* We want to make sure that the next event generates a frame-switch
395 event to the appropriate frame. This seems kludgey to me, but
396 before you take it out, make sure that evaluating something like
397 (select-window (frame-root-window (new-frame))) doesn't end up
398 with your typing being interpreted in the new frame instead of
399 the one you're actually typing in. */
fd2777e0 400 internal_last_event_frame = Qnil;
074577b8 401
ff11dfa1 402 return frame;
dc6f92b8
JB
403}
404
ff11dfa1
JB
405DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
406 "Return the frame that is now selected.")
dc6f92b8
JB
407 ()
408{
409 Lisp_Object tem;
ff11dfa1 410 XSET (tem, Lisp_Frame, selected_frame);
dc6f92b8
JB
411 return tem;
412}
413
ff11dfa1
JB
414DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
415 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
416 (window)
417 Lisp_Object window;
418{
774910eb 419 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 420 return XWINDOW (window)->frame;
dc6f92b8
JB
421}
422
ff11dfa1 423DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
424 "Returns the root-window of FRAME.\n\
425If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
426 (frame)
427 Lisp_Object frame;
dc6f92b8 428{
ff11dfa1
JB
429 if (NILP (frame))
430 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 431 else
ff11dfa1 432 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 433
ff11dfa1 434 return XFRAME (frame)->root_window;
dc6f92b8
JB
435}
436
ff11dfa1
JB
437DEFUN ("frame-selected-window", Fframe_selected_window,
438 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
439 "Return the selected window of frame object FRAME.\n\
440If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
441 (frame)
442 Lisp_Object frame;
dc6f92b8 443{
ff11dfa1
JB
444 if (NILP (frame))
445 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 446 else
ff11dfa1 447 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 448
ff11dfa1 449 return XFRAME (frame)->selected_window;
dc6f92b8
JB
450}
451
ff11dfa1 452DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 453 0, 0, 0,
ff11dfa1 454 "Return a list of all frames.")
dc6f92b8
JB
455 ()
456{
ff11dfa1 457 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
458}
459
ff11dfa1 460/* Return the next frame in the frame list after FRAME.
ff11dfa1
JB
461 If MINIBUF is nil, exclude minibuffer-only frames.
462 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
463 their minibuffer.
464 If MINIBUF is non-nil, and not a window, include all frames. */
dc6f92b8 465Lisp_Object
ff11dfa1
JB
466next_frame (frame, minibuf)
467 Lisp_Object frame;
f9898cc6 468 Lisp_Object minibuf;
dc6f92b8
JB
469{
470 Lisp_Object tail;
471 int passed = 0;
472
ff11dfa1
JB
473 /* There must always be at least one frame in Vframe_list. */
474 if (! CONSP (Vframe_list))
f9898cc6
JB
475 abort ();
476
dbc4e1c1
JB
477 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
478 forever. Forestall that. */
479 CHECK_LIVE_FRAME (frame, 0);
480
dc6f92b8 481 while (1)
ff11dfa1 482 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 483 {
d06a8a56
JB
484 Lisp_Object f = XCONS (tail)->car;
485
dc6f92b8 486 if (passed)
d5e7c279 487 {
d06a8a56
JB
488 /* Decide whether this frame is eligible to be returned. */
489
490 /* If we've looped all the way around without finding any
491 eligible frames, return the original frame. */
492 if (EQ (f, frame))
493 return f;
494
495 /* Let minibuf decide if this frame is acceptable. */
496 if (NILP (minibuf))
497 {
498 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
499 return f;
500 }
501 else if (XTYPE (minibuf) == Lisp_Window)
502 {
503 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
504 return f;
505 }
506 else
ff11dfa1 507 return f;
d5e7c279 508 }
dc6f92b8 509
d06a8a56 510 if (EQ (frame, f))
dc6f92b8
JB
511 passed++;
512 }
513}
514
ff11dfa1 515/* Return the previous frame in the frame list before FRAME.
ff11dfa1
JB
516 If MINIBUF is nil, exclude minibuffer-only frames.
517 If MINIBUF is a window, include only frames using that window for
d06a8a56
JB
518 their minibuffer.
519 If MINIBUF is non-nil and not a window, include all frames. */
dc6f92b8 520Lisp_Object
ff11dfa1
JB
521prev_frame (frame, minibuf)
522 Lisp_Object frame;
f9898cc6 523 Lisp_Object minibuf;
dc6f92b8
JB
524{
525 Lisp_Object tail;
526 Lisp_Object prev;
527
ff11dfa1
JB
528 /* There must always be at least one frame in Vframe_list. */
529 if (! CONSP (Vframe_list))
f9898cc6
JB
530 abort ();
531
dc6f92b8 532 prev = Qnil;
d06a8a56 533 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 534 {
d06a8a56 535 Lisp_Object f = XCONS (tail)->car;
f9898cc6 536
d06a8a56
JB
537 if (XTYPE (f) != Lisp_Frame)
538 abort ();
f9898cc6 539
d06a8a56
JB
540 if (EQ (frame, f) && !NILP (prev))
541 return prev;
f9898cc6 542
d06a8a56
JB
543 /* Decide whether this frame is eligible to be returned,
544 according to minibuf. */
545 if (NILP (minibuf))
546 {
547 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
548 prev = f;
f9898cc6 549 }
d06a8a56
JB
550 else if (XTYPE (minibuf) == Lisp_Window)
551 {
552 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
553 prev = f;
554 }
555 else
556 prev = f;
f9898cc6 557 }
d06a8a56
JB
558
559 /* We've scanned the entire list. */
560 if (NILP (prev))
561 /* We went through the whole frame list without finding a single
562 acceptable frame. Return the original frame. */
563 return frame;
564 else
565 /* There were no acceptable frames in the list before FRAME; otherwise,
566 we would have returned directly from the loop. Since PREV is the last
567 acceptable frame in the list, return it. */
568 return prev;
dc6f92b8
JB
569}
570
ff11dfa1
JB
571DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
572 "Return the next frame in the frame list after FRAME.\n\
a42e9724 573By default, skip minibuffer-only frames.\n\
d06a8a56 574If omitted, FRAME defaults to the selected frame.\n\
8693ca83
JB
575If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
576If MINIFRAME is a window, include only frames using that window for their\n\
d06a8a56 577minibuffer.\n\
8693ca83 578If MINIFRAME is non-nil and not a window, include all frames.")
ff11dfa1 579 (frame, miniframe)
8693ca83 580 Lisp_Object frame, miniframe;
dc6f92b8
JB
581{
582 Lisp_Object tail;
583
ff11dfa1
JB
584 if (NILP (frame))
585 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 586 else
ff11dfa1 587 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 588
ff11dfa1 589 return next_frame (frame, miniframe);
dc6f92b8 590}
dbc4e1c1 591
dc6f92b8 592\f
ff11dfa1
JB
593DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
594 "Delete FRAME, permanently eliminating it from use.\n\
595If omitted, FRAME defaults to the selected frame.\n\
596A frame may not be deleted if its minibuffer is used by other frames.")
597 (frame)
598 Lisp_Object frame;
dc6f92b8 599{
ff11dfa1 600 struct frame *f;
dc6f92b8 601
ff11dfa1 602 if (EQ (frame, Qnil))
dc6f92b8 603 {
ff11dfa1
JB
604 f = selected_frame;
605 XSET (frame, Lisp_Frame, f);
dc6f92b8
JB
606 }
607 else
608 {
ff11dfa1
JB
609 CHECK_FRAME (frame, 0);
610 f = XFRAME (frame);
dc6f92b8
JB
611 }
612
ff11dfa1 613 if (! FRAME_LIVE_P (f))
074577b8 614 return Qnil;
f9898cc6 615
ff11dfa1
JB
616 /* Are there any other frames besides this one? */
617 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
618 error ("Attempt to delete the only frame");
d5e7c279 619
ff11dfa1
JB
620 /* Does this frame have a minibuffer, and is it the surrogate
621 minibuffer for any other frame? */
fd0c2bd1 622 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 623 {
ff11dfa1 624 Lisp_Object frames;
1113d9db 625
ff11dfa1
JB
626 for (frames = Vframe_list;
627 CONSP (frames);
628 frames = XCONS (frames)->cdr)
1113d9db 629 {
ff11dfa1 630 Lisp_Object this = XCONS (frames)->car;
1113d9db 631
ff11dfa1
JB
632 if (! EQ (this, frame)
633 && EQ (frame,
634 (WINDOW_FRAME
1113d9db 635 (XWINDOW
ff11dfa1
JB
636 (FRAME_MINIBUF_WINDOW
637 (XFRAME (this)))))))
638 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 639 }
dc6f92b8
JB
640 }
641
ff11dfa1
JB
642 /* Don't let the frame remain selected. */
643 if (f == selected_frame)
629a12cf 644 Fselect_frame (next_frame (frame, Qt), Qnil);
dc6f92b8 645
ff11dfa1
JB
646 /* Don't allow minibuf_window to remain on a deleted frame. */
647 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 648 {
ff11dfa1 649 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 650 XWINDOW (minibuf_window)->buffer);
ff11dfa1 651 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
652 }
653
4a88b3b0
JB
654 /* Mark all the windows that used to be on FRAME as deleted, and then
655 remove the reference to them. */
656 delete_all_subwindows (XWINDOW (f->root_window));
657 f->root_window = Qnil;
658
ff11dfa1 659 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 660 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 661
8678b9cc
JB
662 /* Since some events are handled at the interrupt level, we may get
663 an event for f at any time; if we zero out the frame's display
664 now, then we may trip up the event-handling code. Instead, we'll
665 promise that the display of the frame must be valid until we have
666 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
667
668 /* I think this should be done with a hook. */
d5e7c279 669#ifdef HAVE_X_WINDOWS
fd0c2bd1 670 if (FRAME_X_P (f))
8678b9cc 671 x_destroy_window (f);
d5e7c279
JB
672#endif
673
8678b9cc
JB
674 f->display.nothing = 0;
675
ff11dfa1 676 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 677 another one. */
ff11dfa1 678 if (f == last_nonminibuf_frame)
d5e7c279 679 {
ff11dfa1 680 Lisp_Object frames;
1113d9db 681
ff11dfa1 682 last_nonminibuf_frame = 0;
d5e7c279 683
ff11dfa1
JB
684 for (frames = Vframe_list;
685 CONSP (frames);
686 frames = XCONS (frames)->cdr)
d5e7c279 687 {
ff11dfa1
JB
688 f = XFRAME (XCONS (frames)->car);
689 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 690 {
ff11dfa1 691 last_nonminibuf_frame = f;
d5e7c279
JB
692 break;
693 }
694 }
695 }
dc6f92b8 696
ff11dfa1
JB
697 /* If we've deleted Vdefault_minibuffer_frame, try to find another
698 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 699 with other windows. */
ff11dfa1 700 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 701 {
ff11dfa1 702 Lisp_Object frames;
1113d9db 703
ff11dfa1
JB
704 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
705 Lisp_Object frame_with_minibuf = Qnil;
1113d9db 706
ff11dfa1
JB
707 for (frames = Vframe_list;
708 CONSP (frames);
709 frames = XCONS (frames)->cdr)
1113d9db 710 {
ff11dfa1 711 Lisp_Object this = XCONS (frames)->car;
1113d9db 712
ff11dfa1 713 if (XTYPE (this) != Lisp_Frame)
1113d9db 714 abort ();
ff11dfa1 715 f = XFRAME (this);
1113d9db 716
fd0c2bd1 717 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 718 {
ff11dfa1
JB
719 frame_with_minibuf = this;
720 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
721 break;
722 }
723 }
724
ff11dfa1
JB
725 /* We know that there must be some frame with a minibuffer out
726 there. If this were not true, all of the frames present
1113d9db 727 would have to be minibufferless, which implies that at some
ff11dfa1 728 point their minibuffer frames must have been deleted, but
1113d9db 729 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
730 minibuffer frames. */
731 if (NILP (frame_with_minibuf))
1113d9db
JB
732 abort ();
733
ff11dfa1 734 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
735 }
736
dc6f92b8
JB
737 return Qnil;
738}
739\f
740/* Return mouse position in character cell units. */
741
f9898cc6 742DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 743 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
f9898cc6 744If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 745to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
746and nil for X and Y.")
747 ()
dc6f92b8 748{
ff11dfa1 749 FRAME_PTR f;
dbc4e1c1 750 Lisp_Object lispy_dummy;
fd2777e0 751 enum scroll_bar_part party_dummy;
dbc4e1c1
JB
752 Lisp_Object x, y;
753 unsigned long long_dummy;
dc6f92b8 754
f9898cc6 755 if (mouse_position_hook)
dbc4e1c1
JB
756 (*mouse_position_hook) (&f,
757 &lispy_dummy, &party_dummy,
758 &x, &y,
759 &long_dummy);
f9898cc6
JB
760 else
761 {
ff11dfa1 762 f = selected_frame;
f9898cc6
JB
763 x = y = Qnil;
764 }
dc6f92b8 765
dbc4e1c1
JB
766 XSET (lispy_dummy, Lisp_Frame, f);
767 return Fcons (lispy_dummy, Fcons (make_number (x), make_number (y)));
dc6f92b8
JB
768}
769
770DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
ff11dfa1
JB
771 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
772WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
773 (frame, x, y)
774 Lisp_Object frame, x, y;
dc6f92b8 775{
ff11dfa1 776 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
777 CHECK_NUMBER (x, 2);
778 CHECK_NUMBER (y, 1);
779
dbc4e1c1 780 /* I think this should be done with a hook. */
dc6f92b8 781#ifdef HAVE_X_WINDOWS
fd0c2bd1 782 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 783 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 784 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
785#endif
786
787 return Qnil;
788}
789\f
ff11dfa1 790DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1aa66088 791 0, 1, 0,
ff11dfa1 792 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83
JB
793Also raises the frame so that nothing obscures it.\n\
794If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
795 (frame)
796 Lisp_Object frame;
dc6f92b8 797{
1aa66088 798 if (NILP (frame))
7500877e 799 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 800
ff11dfa1 801 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 802
dbc4e1c1 803 /* I think this should be done with a hook. */
fd0c2bd1
JB
804#ifdef HAVE_X_WINDOWS
805 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 806 x_make_frame_visible (XFRAME (frame));
fd0c2bd1 807#endif
dc6f92b8 808
ff11dfa1 809 return frame;
dc6f92b8
JB
810}
811
ff11dfa1 812DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1aa66088 813 0, 1, "",
8693ca83
JB
814 "Make the frame FRAME invisible (assuming it is an X-window).\n\
815If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
816 (frame)
817 Lisp_Object frame;
dc6f92b8 818{
1aa66088 819 if (NILP (frame))
7500877e 820 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 821
ff11dfa1 822 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 823
dbc4e1c1 824 /* I think this should be done with a hook. */
fd0c2bd1
JB
825#ifdef HAVE_X_WINDOWS
826 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 827 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 828#endif
dc6f92b8
JB
829
830 return Qnil;
831}
832
ff11dfa1 833DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 834 0, 1, "",
8693ca83
JB
835 "Make the frame FRAME into an icon.\n\
836If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
837 (frame)
838 Lisp_Object frame;
dc6f92b8 839{
1aa66088 840 if (NILP (frame))
7500877e 841 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 842
ff11dfa1 843 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 844
dbc4e1c1 845 /* I think this should be done with a hook. */
fd0c2bd1
JB
846#ifdef HAVE_X_WINDOWS
847 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 848 x_iconify_frame (XFRAME (frame));
fd0c2bd1 849#endif
dc6f92b8
JB
850
851 return Qnil;
852}
853
ff11dfa1 854DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 855 1, 1, 0,
ff11dfa1
JB
856 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
857A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 858a window system, it may not show at all.\n\
fd0c2bd1 859Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
860 (frame)
861 Lisp_Object frame;
dc6f92b8 862{
ff11dfa1 863 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 864
a42e9724 865 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 866 return Qt;
a42e9724 867 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 868 return Qicon;
dc6f92b8
JB
869 return Qnil;
870}
871
ff11dfa1 872DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 873 0, 0, 0,
ff11dfa1 874 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
875 ()
876{
ff11dfa1
JB
877 Lisp_Object tail, frame;
878 struct frame *f;
dc6f92b8
JB
879 Lisp_Object value;
880
881 value = Qnil;
ff11dfa1 882 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 883 {
ff11dfa1
JB
884 frame = XCONS (tail)->car;
885 if (XTYPE (frame) != Lisp_Frame)
dc6f92b8 886 continue;
ff11dfa1 887 f = XFRAME (frame);
a42e9724 888 if (FRAME_VISIBLE_P (f))
ff11dfa1 889 value = Fcons (frame, value);
dc6f92b8
JB
890 }
891 return value;
892}
d5e7c279
JB
893
894
dbc4e1c1
JB
895DEFUN ("frame-to-front", Fframe_to_front, Sframe_to_front, 1, 1, 0,
896 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
897If FRAME is invisible, make it visible.\n\
898If Emacs is displaying on an ordinary terminal or some other device which\n\
899doesn't support multiple overlapping frames, this function does nothing.")
900 (frame)
901 Lisp_Object frame;
902{
903 CHECK_LIVE_FRAME (frame, 0);
904
905 if (frame_raise_lower_hook)
906 (*frame_raise_lower_hook) (XFRAME (frame), 1);
907
908 return Qnil;
909}
910
911DEFUN ("frame-to-back", Fframe_to_back, Sframe_to_back, 1, 1, 0,
912 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
913If Emacs is displaying on an ordinary terminal or some other device which\n\
914doesn't support multiple overlapping frames, this function does nothing.")
915 (frame)
916 Lisp_Object frame;
917{
918 CHECK_LIVE_FRAME (frame, 0);
919
920 if (frame_raise_lower_hook)
921 (*frame_raise_lower_hook) (XFRAME (frame), 0);
922
923 return Qnil;
924}
925
d5e7c279 926\f
ff11dfa1 927DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 928 1, 2, 0,
ff11dfa1 929 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
930In other words, switch-frame events caused by events in FRAME will\n\
931request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
932FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 933\n\
a42e9724 934If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 935cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 936\n\
a42e9724
JB
937Focus redirection is useful for temporarily redirecting keystrokes to\n\
938a surrogate minibuffer frame when a frame doesn't have its own\n\
939minibuffer window.\n\
d5e7c279 940\n\
a42e9724
JB
941A frame's focus redirection can be changed by select-frame. If frame\n\
942FOO is selected, and then a different frame BAR is selected, any\n\
943frames redirecting their focus to FOO are shifted to redirect their\n\
944focus to BAR. This allows focus redirection to work properly when the\n\
945user switches from one frame to another using `select-window'.\n\
946\n\
947This means that a frame whose focus is redirected to itself is treated\n\
948differently from a frame whose focus is redirected to nil; the former\n\
949is affected by select-frame, while the latter is not.\n\
950\n\
951The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
952 (frame, focus_frame)
953 Lisp_Object frame, focus_frame;
d5e7c279 954{
ff11dfa1 955 CHECK_LIVE_FRAME (frame, 0);
f9898cc6 956
a42e9724 957 if (! NILP (focus_frame))
ff11dfa1 958 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 959
ff11dfa1 960 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 961
ff11dfa1
JB
962 if (frame_rehighlight_hook)
963 (*frame_rehighlight_hook) ();
d5e7c279
JB
964
965 return Qnil;
966}
967
968
ff11dfa1
JB
969DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
970 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 971This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
972See `redirect-frame-focus'.")
973 (frame)
974 Lisp_Object frame;
d5e7c279 975{
ff11dfa1 976 CHECK_LIVE_FRAME (frame, 0);
a42e9724 977
ff11dfa1 978 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
979}
980
981
dc6f92b8
JB
982\f
983Lisp_Object
ff11dfa1
JB
984get_frame_param (frame, prop)
985 register struct frame *frame;
dc6f92b8
JB
986 Lisp_Object prop;
987{
988 register Lisp_Object tem;
989
ff11dfa1 990 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
991 if (EQ (tem, Qnil))
992 return tem;
993 return Fcdr (tem);
994}
995
996void
fd0c2bd1 997store_in_alist (alistptr, prop, val)
dc6f92b8 998 Lisp_Object *alistptr, val;
fd0c2bd1 999 Lisp_Object prop;
dc6f92b8
JB
1000{
1001 register Lisp_Object tem;
dc6f92b8 1002
dc6f92b8
JB
1003 tem = Fassq (prop, *alistptr);
1004 if (EQ (tem, Qnil))
1005 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1006 else
1007 Fsetcdr (tem, val);
1008}
1009
1010void
ff11dfa1
JB
1011store_frame_param (f, prop, val)
1012 struct frame *f;
dc6f92b8
JB
1013 Lisp_Object prop, val;
1014{
1015 register Lisp_Object tem;
1016
ff11dfa1 1017 tem = Fassq (prop, f->param_alist);
dc6f92b8 1018 if (EQ (tem, Qnil))
ff11dfa1 1019 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1020 else
1021 Fsetcdr (tem, val);
bc93c097
JB
1022
1023 if (EQ (prop, Qminibuffer)
1024 && XTYPE (val) == Lisp_Window)
1025 {
1026 if (! MINI_WINDOW_P (XWINDOW (val)))
1027 error ("Surrogate minibuffer windows must be minibuffer windows.");
1028
fd0c2bd1 1029 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
ff11dfa1 1030 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
bc93c097
JB
1031
1032 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1033 f->minibuffer_window = val;
bc93c097 1034 }
dc6f92b8
JB
1035}
1036
ff11dfa1
JB
1037DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1038 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1039It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1040The meaningful PARMs depend on the kind of frame.\n\
1041If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1042 (frame)
1043 Lisp_Object frame;
dc6f92b8
JB
1044{
1045 Lisp_Object alist;
ff11dfa1 1046 struct frame *f;
dc6f92b8 1047
ff11dfa1
JB
1048 if (EQ (frame, Qnil))
1049 f = selected_frame;
dc6f92b8
JB
1050 else
1051 {
ff11dfa1
JB
1052 CHECK_FRAME (frame, 0);
1053 f = XFRAME (frame);
dc6f92b8
JB
1054 }
1055
ff11dfa1 1056 if (f->display.nothing == 0)
dc6f92b8
JB
1057 return Qnil;
1058
ff11dfa1 1059 alist = Fcopy_alist (f->param_alist);
fd0c2bd1
JB
1060 store_in_alist (&alist, Qname, f->name);
1061 store_in_alist (&alist, Qheight, make_number (f->height));
1062 store_in_alist (&alist, Qwidth, make_number (f->width));
1063 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1064 store_in_alist (&alist, Qminibuffer,
39acc701 1065 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
fd0c2bd1
JB
1066 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1067 : FRAME_MINIBUF_WINDOW (f))));
1068 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
fa8fdbf9 1069 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
fd0c2bd1 1070
dbc4e1c1 1071 /* I think this should be done with a hook. */
fd0c2bd1
JB
1072#ifdef HAVE_X_WINDOWS
1073 if (FRAME_X_P (f))
ff11dfa1 1074 x_report_frame_params (f, &alist);
fd0c2bd1 1075#endif
dc6f92b8
JB
1076 return alist;
1077}
1078
ff11dfa1
JB
1079DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1080 Smodify_frame_parameters, 2, 2, 0,
1081 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1082ALIST is an alist of parameters to change and their new values.\n\
1083Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1084The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1085 (frame, alist)
1086 Lisp_Object frame, alist;
dc6f92b8 1087{
fd0c2bd1 1088 FRAME_PTR f;
dc6f92b8
JB
1089 register Lisp_Object tail, elt, prop, val;
1090
ff11dfa1
JB
1091 if (EQ (frame, Qnil))
1092 f = selected_frame;
dc6f92b8
JB
1093 else
1094 {
ff11dfa1
JB
1095 CHECK_LIVE_FRAME (frame, 0);
1096 f = XFRAME (frame);
dc6f92b8
JB
1097 }
1098
dbc4e1c1 1099 /* I think this should be done with a hook. */
fd0c2bd1
JB
1100#ifdef HAVE_X_WINDOWS
1101 if (FRAME_X_P (f))
1102#if 1
1103 x_set_frame_parameters (f, alist);
1104#else
dc6f92b8
JB
1105 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1106 {
1107 elt = Fcar (tail);
1108 prop = Fcar (elt);
1109 val = Fcdr (elt);
fd0c2bd1 1110 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
ff11dfa1 1111 store_frame_param (f, prop, val);
dc6f92b8 1112 }
fd0c2bd1
JB
1113#endif
1114#endif
dc6f92b8
JB
1115
1116 return Qnil;
1117}
1118\f
a26a1f95
RS
1119DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1120 0, 1, 0,
1121 "Height in pixels of a line in the font in frame FRAME.\n\
1122If FRAME is omitted, the selected frame is used.\n\
1123For a terminal frame, the value is always 1.")
ff11dfa1
JB
1124 (frame)
1125 Lisp_Object frame;
dc6f92b8 1126{
a26a1f95 1127 struct frame *f;
dc6f92b8 1128
a26a1f95
RS
1129 if (NILP (frame))
1130 f = selected_frame;
1131 else
1132 {
1133 CHECK_FRAME (frame, 0);
1134 f = XFRAME (frame);
1135 }
1136
1137#ifdef HAVE_X_WINDOWS
1138 if (FRAME_X_P (f))
1139 return make_number (x_char_height (f));
1140 else
dc6d9681 1141#endif
a26a1f95
RS
1142 return make_number (1);
1143}
dc6d9681 1144
dc6f92b8 1145
a26a1f95
RS
1146DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1147 0, 1, 0,
1148 "Width in pixels of characters in the font in frame FRAME.\n\
1149If FRAME is omitted, the selected frame is used.\n\
1150The width is the same for all characters, because\n\
1151currently Emacs supports only fixed-width fonts.\n\
1152For a terminal screen, the value is always 1.")
1153 (frame)
1154 Lisp_Object frame;
dc6f92b8 1155{
a26a1f95
RS
1156 struct frame *f;
1157
1158 if (NILP (frame))
1159 f = selected_frame;
1160 else
1161 {
1162 CHECK_FRAME (frame, 0);
1163 f = XFRAME (frame);
1164 }
1165
1166#ifdef HAVE_X_WINDOWS
1167 if (FRAME_X_P (f))
1168 return make_number (x_char_width (f));
1169 else
1170#endif
1171 return make_number (1);
dc6f92b8
JB
1172}
1173
a26a1f95
RS
1174DEFUN ("frame-pixel-height", Fframe_pixel_height,
1175 Sframe_pixel_height, 0, 1, 0,
1176 "Return a FRAME's heightin pixels.\n\
1177For a terminal frame, the result really gives the sizes in characters.\n\
1178If FRAME is omitted, the selected frame is used.")
1179 (frame)
1180 Lisp_Object frame;
dc6f92b8 1181{
a26a1f95
RS
1182 struct frame *f;
1183
1184 if (NILP (frame))
1185 f = selected_frame;
1186 else
1187 {
1188 CHECK_FRAME (frame, 0);
1189 f = XFRAME (frame);
1190 }
1191
1192#ifdef HAVE_X_WINDOWS
1193 if (FRAME_X_P (f))
1194 return make_number (x_pixel_height (f));
1195 else
dc6d9681 1196#endif
a26a1f95
RS
1197 return make_number (FRAME_HEIGHT (f));
1198}
1199
1200DEFUN ("frame-pixel-width", Fframe_pixel_width,
1201 Sframe_pixel_width, 0, 1, 0,
1202 "Return FRAME's width in pixels.\n\
1203For a terminal frame, the result really gives the sizes in characters.\n\
1204If FRAME is omitted, the selected frame is used.")
1205 (frame)
1206 Lisp_Object frame;
1207{
1208 struct frame *f;
1209
1210 if (NILP (frame))
1211 f = selected_frame;
1212 else
1213 {
1214 CHECK_FRAME (frame, 0);
1215 f = XFRAME (frame);
1216 }
dc6f92b8 1217
a26a1f95
RS
1218#ifdef HAVE_X_WINDOWS
1219 if (FRAME_X_P (f))
1220 return make_number (x_pixel_width (f));
1221 else
1222#endif
1223 return make_number (FRAME_WIDTH (f));
1224}
1225\f
ff11dfa1
JB
1226DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1227 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1228Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1229but that the idea of the actual height of the frame should not be changed.")
1230 (frame, rows, pretend)
fd0c2bd1 1231 Lisp_Object frame, rows, pretend;
dc6f92b8 1232{
ff11dfa1 1233 register struct frame *f;
dc6f92b8
JB
1234
1235 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1236 if (NILP (frame))
1237 f = selected_frame;
dc6f92b8
JB
1238 else
1239 {
ff11dfa1
JB
1240 CHECK_LIVE_FRAME (frame, 0);
1241 f = XFRAME (frame);
dc6f92b8
JB
1242 }
1243
dbc4e1c1 1244 /* I think this should be done with a hook. */
fd0c2bd1
JB
1245#ifdef HAVE_X_WINDOWS
1246 if (FRAME_X_P (f))
dc6f92b8 1247 {
ff11dfa1
JB
1248 if (XINT (rows) != f->width)
1249 x_set_window_size (f, f->width, XINT (rows));
dc6f92b8
JB
1250 }
1251 else
fd0c2bd1
JB
1252#endif
1253 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1254 return Qnil;
1255}
1256
ff11dfa1
JB
1257DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1258 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1259Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1260but that the idea of the actual width of the frame should not be changed.")
1261 (frame, cols, pretend)
fd0c2bd1 1262 Lisp_Object frame, cols, pretend;
dc6f92b8 1263{
ff11dfa1 1264 register struct frame *f;
dc6f92b8 1265 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1266 if (NILP (frame))
1267 f = selected_frame;
dc6f92b8
JB
1268 else
1269 {
ff11dfa1
JB
1270 CHECK_LIVE_FRAME (frame, 0);
1271 f = XFRAME (frame);
dc6f92b8
JB
1272 }
1273
dbc4e1c1 1274 /* I think this should be done with a hook. */
fd0c2bd1
JB
1275#ifdef HAVE_X_WINDOWS
1276 if (FRAME_X_P (f))
dc6f92b8 1277 {
ff11dfa1
JB
1278 if (XINT (cols) != f->width)
1279 x_set_window_size (f, XINT (cols), f->height);
dc6f92b8
JB
1280 }
1281 else
fd0c2bd1
JB
1282#endif
1283 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1284 return Qnil;
1285}
1286
ff11dfa1
JB
1287DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1288 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1289 (frame, cols, rows)
1290 Lisp_Object frame, cols, rows;
dc6f92b8 1291{
ff11dfa1 1292 register struct frame *f;
dc6f92b8
JB
1293 int mask;
1294
ff11dfa1 1295 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1296 CHECK_NUMBER (cols, 2);
1297 CHECK_NUMBER (rows, 1);
ff11dfa1 1298 f = XFRAME (frame);
dc6f92b8 1299
dbc4e1c1 1300 /* I think this should be done with a hook. */
fd0c2bd1
JB
1301#ifdef HAVE_X_WINDOWS
1302 if (FRAME_X_P (f))
dc6f92b8 1303 {
ff11dfa1
JB
1304 if (XINT (rows) != f->height || XINT (cols) != f->width)
1305 x_set_window_size (f, XINT (cols), XINT (rows));
dc6f92b8
JB
1306 }
1307 else
fd0c2bd1
JB
1308#endif
1309 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1310
1311 return Qnil;
1312}
1313
ff11dfa1
JB
1314DEFUN ("set-frame-position", Fset_frame_position,
1315 Sset_frame_position, 3, 3, 0,
1316 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
f9898cc6 1317If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
ff11dfa1 1318the leftmost or bottommost position FRAME could occupy without going\n\
fd0c2bd1 1319off the screen.")
ff11dfa1
JB
1320 (frame, xoffset, yoffset)
1321 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1322{
ff11dfa1 1323 register struct frame *f;
dc6f92b8
JB
1324 int mask;
1325
ff11dfa1 1326 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1327 CHECK_NUMBER (xoffset, 1);
1328 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1329 f = XFRAME (frame);
dc6f92b8 1330
dbc4e1c1 1331 /* I think this should be done with a hook. */
fd0c2bd1
JB
1332#ifdef HAVE_X_WINDOWS
1333 if (FRAME_X_P (f))
ff11dfa1 1334 x_set_offset (f, XINT (xoffset), XINT (yoffset));
fd0c2bd1 1335#endif
dc6f92b8
JB
1336
1337 return Qt;
1338}
dc6d9681 1339
dc6f92b8 1340\f
dc6f92b8
JB
1341#ifndef HAVE_X11
1342DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1343 3, 3, "",
ff11dfa1
JB
1344 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1345Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
dc6f92b8
JB
1346the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1347specify defaults for some sizes/positions. If GEO specifies everything,\n\
1348the mouse is not used.\n\
ff11dfa1
JB
1349Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1350 (frame, name, geo)
1351 Lisp_Object frame;
dc6f92b8
JB
1352 Lisp_Object name;
1353 Lisp_Object geo;
1354{
1355 int vals[4];
1356 Lisp_Object nums[4];
1357 int i;
1358
ff11dfa1 1359 CHECK_FRAME (frame, 0);
dc6f92b8
JB
1360 CHECK_STRING (name, 1);
1361 CHECK_STRING (geo, 2);
1362
ff11dfa1 1363 switch (XFRAME (frame)->output_method)
dc6f92b8
JB
1364 {
1365 case output_x_window:
ff11dfa1 1366 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
dc6f92b8
JB
1367 XSTRING (geo)->data, XSTRING (name)->data);
1368 break;
1369
1370 default:
1371 return Qnil;
1372 }
1373
1374 for (i = 0; i < 4; i++)
1375 XFASTINT (nums[i]) = vals[i];
ff11dfa1 1376 return Fcons (frame, Flist (4, nums));
dc6f92b8
JB
1377 return Qnil;
1378}
1379#endif /* not HAVE_X11 */
1380\f
ff11dfa1 1381choose_minibuf_frame ()
dc6f92b8 1382{
ff11dfa1
JB
1383 /* For lowest-level minibuf, put it on currently selected frame
1384 if frame has a minibuffer. */
d06a8a56 1385
dc6f92b8 1386 if (minibuf_level == 0
ff11dfa1 1387 && selected_frame != 0
d06a8a56 1388 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1389 {
d06a8a56
JB
1390 /* I don't think that any frames may validly have a null minibuffer
1391 window anymore. */
1392 if (NILP (selected_frame->minibuffer_window))
1393 abort ();
1394
ff11dfa1 1395 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1396 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1397 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1398 }
1399}
1400\f
ff11dfa1 1401syms_of_frame ()
dc6f92b8 1402{
fd0c2bd1 1403 /*&&& init symbols here &&&*/
ff11dfa1 1404 Qframep = intern ("framep");
ff11dfa1 1405 staticpro (&Qframep);
dbc4e1c1
JB
1406 Qframe_live_p = intern ("frame-live-p");
1407 staticpro (&Qframe_live_p);
fd0c2bd1
JB
1408 Qheight = intern ("height");
1409 staticpro (&Qheight);
1410 Qicon = intern ("icon");
1411 staticpro (&Qicon);
1412 Qminibuffer = intern ("minibuffer");
bc93c097 1413 staticpro (&Qminibuffer);
fd0c2bd1
JB
1414 Qmodeline = intern ("modeline");
1415 staticpro (&Qmodeline);
1416 Qname = intern ("name");
1417 staticpro (&Qname);
fd0c2bd1
JB
1418 Qonly = intern ("only");
1419 staticpro (&Qonly);
1420 Qunsplittable = intern ("unsplittable");
1421 staticpro (&Qunsplittable);
1422 Qwidth = intern ("width");
1423 staticpro (&Qwidth);
1424 Qx = intern ("x");
1425 staticpro (&Qx);
fa8fdbf9
RS
1426 Qmenu_bar_lines = intern ("menu-bar-lines");
1427 staticpro (&Qmenu_bar_lines);
dc6f92b8 1428
ff11dfa1 1429 staticpro (&Vframe_list);
dc6f92b8 1430
ff11dfa1
JB
1431 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1432 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1433
1434 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1435 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1436 Vemacs_iconified = Qnil;
1437
ff11dfa1
JB
1438 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1439 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1440\n\
ff11dfa1 1441Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1442appropriate surrogate.\n\
1443\n\
1444Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1445frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1446minibuffer, no matter what this variable is set to. This means that\n\
1447this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1448current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1449displayed.");
ff11dfa1 1450 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1451
ff11dfa1
JB
1452 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1453 "Alist of default values for frame creation.\n\
5bce042c 1454These may be set in your init file, like this:\n\
ff11dfa1 1455 (setq default-frame-alist '((width . 80) (height . 55)))\n\
5bce042c
JB
1456These override values given in window system configuration data, like\n\
1457X Windows' defaults database.\n\
ff11dfa1
JB
1458For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1459For values specific to the separate minibuffer frame, see\n\
1460`minibuffer-frame-alist'.");
1461 Vdefault_frame_alist = Qnil;
1462
1463 defsubr (&Sframep);
dbc4e1c1 1464 defsubr (&Sframe_live_p);
ff11dfa1
JB
1465 defsubr (&Sselect_frame);
1466 defsubr (&Sselected_frame);
1467 defsubr (&Swindow_frame);
1468 defsubr (&Sframe_root_window);
1469 defsubr (&Sframe_selected_window);
1470 defsubr (&Sframe_list);
1471 defsubr (&Snext_frame);
1472 defsubr (&Sdelete_frame);
f9898cc6 1473 defsubr (&Smouse_position);
dc6f92b8
JB
1474 defsubr (&Sset_mouse_position);
1475#if 0
ff11dfa1
JB
1476 defsubr (&Sframe_configuration);
1477 defsubr (&Srestore_frame_configuration);
dc6f92b8 1478#endif
ff11dfa1
JB
1479 defsubr (&Smake_frame_visible);
1480 defsubr (&Smake_frame_invisible);
1481 defsubr (&Siconify_frame);
1482 defsubr (&Sframe_visible_p);
1483 defsubr (&Svisible_frame_list);
dbc4e1c1
JB
1484 defsubr (&Sframe_to_front);
1485 defsubr (&Sframe_to_back);
ff11dfa1
JB
1486 defsubr (&Sredirect_frame_focus);
1487 defsubr (&Sframe_focus);
1488 defsubr (&Sframe_parameters);
1489 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
1490 defsubr (&Sframe_char_height);
1491 defsubr (&Sframe_char_width);
1492 defsubr (&Sframe_pixel_height);
1493 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
1494 defsubr (&Sset_frame_height);
1495 defsubr (&Sset_frame_width);
1496 defsubr (&Sset_frame_size);
1497 defsubr (&Sset_frame_position);
dc6f92b8
JB
1498#ifndef HAVE_X11
1499 defsubr (&Srubber_band_rectangle);
1500#endif /* HAVE_X11 */
1501}
e5d77022 1502
2f0b07e0
JB
1503keys_of_frame ()
1504{
1505 initial_define_lispy_key (global_map, "switch-frame", "select-frame");
1506}
a26a1f95 1507\f
d06a8a56 1508#else /* not MULTI_FRAME */
fd0c2bd1 1509
cc38027b
JB
1510/* If we're not using multi-frame stuff, we still need to provide some
1511 support functions. */
1512
1513/* Unless this function is defined, providing set-frame-height and
1514 set-frame-width doesn't help compatibility any, since they both
1515 want this as their first argument. */
1516DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1517 "Return the frame that is now selected.")
1518 ()
1519{
1520 Lisp_Object tem;
1521 XFASTINT (tem) = 0;
1522 return tem;
1523}
fd0c2bd1
JB
1524
1525DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1526 "Specify that the frame FRAME has LINES lines.\n\
1527Optional third arg non-nil means that redisplay should use LINES lines\n\
1528but that the idea of the actual height of the frame should not be changed.")
1529 (frame, rows, pretend)
1530 Lisp_Object frame, rows, pretend;
1531{
1532 CHECK_NUMBER (rows, 0);
1533
1534 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1535 return Qnil;
1536}
1537
1538DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1539 "Specify that the frame FRAME has COLS columns.\n\
1540Optional third arg non-nil means that redisplay should use COLS columns\n\
1541but that the idea of the actual width of the frame should not be changed.")
1542 (frame, cols, pretend)
1543 Lisp_Object frame, cols, pretend;
1544{
1545 CHECK_NUMBER (cols, 0);
1546
1547 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1548 return Qnil;
1549}
1550
1551DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1552 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1553 (frame, cols, rows)
1554 Lisp_Object frame, cols, rows;
1555{
1556 CHECK_NUMBER (cols, 2);
1557 CHECK_NUMBER (rows, 1);
1558
1559 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1560
1561 return Qnil;
1562}
1563
cc38027b
JB
1564DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
1565 "Return number of lines available for display on selected frame.")
1566 ()
1567{
1568 return make_number (FRAME_HEIGHT (selected_frame));
1569}
1570
1571DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1572 "Return number of columns available for display on selected frame.")
1573 ()
1574{
1575 return make_number (FRAME_WIDTH (selected_frame));
1576}
1577
a26a1f95
RS
1578DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1579 0, 1, 0,
1580 "Height in pixels of a line in the font in frame FRAME.\n\
1581If FRAME is omitted, the selected frame is used.\n\
1582For a terminal frame, the value is always 1.")
1583 (frame)
1584 Lisp_Object frame;
1585{
1586 return make_number (1);
1587}
1588
1589
1590DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1591 0, 1, 0,
1592 "Width in pixels of characters in the font in frame FRAME.\n\
1593If FRAME is omitted, the selected frame is used.\n\
1594The width is the same for all characters, because\n\
1595currently Emacs supports only fixed-width fonts.\n\
1596For a terminal screen, the value is always 1.")
1597 (frame)
1598 Lisp_Object frame;
1599{
1600 return make_number (1);
1601}
1602
1603DEFUN ("frame-pixel-height", Fframe_pixel_height,
1604 Sframe_pixel_height, 0, 1, 0,
1605 "Return FRAME's height in pixels.\n\
1606For a terminal frame, the result really gives the height in characters.\n\
1607If FRAME is omitted, the selected frame is used.")
1608 (frame)
1609 Lisp_Object frame;
1610{
1611 return make_number (FRAME_HEIGHT (f));
1612}
1613
1614DEFUN ("frame-pixel-width", Fframe_pixel_width,
1615 Sframe_pixel_width, 0, 1, 0,
1616 "Return FRAME's width in pixels.\n\
1617For a terminal frame, the result really gives the width in characters.\n\
1618If FRAME is omitted, the selected frame is used.")
1619 (frame)
1620 Lisp_Object frame;
1621{
1622 return make_number (FRAME_WIDTH (f));
1623}
1624
cc38027b
JB
1625/* These are for backward compatibility with Emacs 18. */
1626
fd0c2bd1
JB
1627DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1628 "Tell redisplay that the screen has LINES lines.\n\
1629Optional second arg non-nil means that redisplay should use LINES lines\n\
1630but that the idea of the actual height of the screen should not be changed.")
1631 (lines, pretend)
1632 Lisp_Object lines, pretend;
1633{
1634 CHECK_NUMBER (lines, 0);
1635
1636 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1637 return Qnil;
1638}
1639
1640DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1641 "Tell redisplay that the screen has COLS columns.\n\
1642Optional second arg non-nil means that redisplay should use COLS columns\n\
1643but that the idea of the actual width of the screen should not be changed.")
1644 (cols, pretend)
1645 Lisp_Object cols, pretend;
1646{
1647 CHECK_NUMBER (cols, 0);
1648
1649 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1650 return Qnil;
1651}
1652
fd0c2bd1
JB
1653syms_of_frame ()
1654{
a26a1f95
RS
1655 defsubr (&Sselected_frame);
1656 defsubr (&Sframe_char_height);
1657 defsubr (&Sframe_char_width);
1658 defsubr (&Sframe_pixel_height);
1659 defsubr (&Sframe_pixel_width);
fd0c2bd1
JB
1660 defsubr (&Sset_frame_height);
1661 defsubr (&Sset_frame_width);
1662 defsubr (&Sset_frame_size);
1663 defsubr (&Sset_screen_height);
1664 defsubr (&Sset_screen_width);
1665 defsubr (&Sframe_height);
1666 Ffset (intern ("screen-height"), intern ("frame-height"));
1667 defsubr (&Sframe_width);
1668 Ffset (intern ("screen-width"), intern ("frame-width"));
1669}
1670
2f0b07e0
JB
1671keys_of_frame ()
1672{
1673}
1674
fd0c2bd1
JB
1675#endif /* not MULTI_FRAME */
1676
1677
1678
1679