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