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