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