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