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