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