Fix erroneous comment syntax.
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
3a22ee35 2 Copyright (C) 1993, 1994 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
18160b98 20#include <config.h>
565620a5
RS
21
22#include <stdio.h>
cc38027b
JB
23#include "lisp.h"
24#include "frame.h"
bc1ed486 25#include "termhooks.h"
f769f1b2 26#include "window.h"
87485d6f
MW
27#ifdef MSDOS
28#include "msdos.h"
29#endif
e5d77022 30
ff11dfa1 31#ifdef MULTI_FRAME
e5d77022 32
bff19c8d 33#include "buffer.h"
dc6f92b8 34
2f0b07e0
JB
35/* These help us bind and responding to switch-frame events. */
36#include "commands.h"
37#include "keyboard.h"
38
dc6f92b8 39Lisp_Object Vemacs_iconified;
ff11dfa1
JB
40Lisp_Object Vframe_list;
41Lisp_Object Vterminal_frame;
42Lisp_Object Vdefault_minibuffer_frame;
43Lisp_Object Vdefault_frame_alist;
fd0c2bd1
JB
44
45/* Evaluate this expression to rebuild the section of syms_of_frame
46 that initializes and staticpros the symbols declared below. Note
47 that Emacs 18 has a bug that keeps C-x C-e from being able to
48 evaluate this expression.
49
50(progn
51 ;; Accumulate a list of the symbols we want to initialize from the
52 ;; declarations at the top of the file.
53 (goto-char (point-min))
54 (search-forward "/\*&&& symbols declared here &&&*\/\n")
55 (let (symbol-list)
56 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
57 (setq symbol-list
58 (cons (buffer-substring (match-beginning 1) (match-end 1))
59 symbol-list))
60 (forward-line 1))
61 (setq symbol-list (nreverse symbol-list))
62 ;; Delete the section of syms_of_... where we initialize the symbols.
63 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
64 (let ((start (point)))
65 (while (looking-at "^ Q")
66 (forward-line 2))
67 (kill-region start (point)))
68 ;; Write a new symbol initialization section.
69 (while symbol-list
70 (insert (format " %s = intern (\"" (car symbol-list)))
71 (let ((start (point)))
72 (insert (substring (car symbol-list) 1))
73 (subst-char-in-region start (point) ?_ ?-))
74 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
75 (setq symbol-list (cdr symbol-list)))))
76 */
77
78/*&&& symbols declared here &&&*/
79Lisp_Object Qframep;
dbc4e1c1 80Lisp_Object Qframe_live_p;
fd0c2bd1
JB
81Lisp_Object Qheight;
82Lisp_Object Qicon;
bc93c097 83Lisp_Object Qminibuffer;
fd0c2bd1
JB
84Lisp_Object Qmodeline;
85Lisp_Object Qname;
fd0c2bd1
JB
86Lisp_Object Qonly;
87Lisp_Object Qunsplittable;
fa8fdbf9 88Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
89Lisp_Object Qwidth;
90Lisp_Object Qx;
f7af3f7b 91Lisp_Object Qvisible;
dc6f92b8
JB
92
93extern Lisp_Object Vminibuffer_list;
94extern Lisp_Object get_minibuffer ();
84386599
RS
95extern Lisp_Object Fhandle_switch_frame ();
96extern Lisp_Object Fredirect_frame_focus ();
dc6f92b8 97\f
ff11dfa1
JB
98DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
99 "Return non-nil if OBJECT is a frame.\n\
100Value is t for a termcap frame (a character-only terminal),\n\
87485d6f
MW
101`x' for an Emacs frame that is really an X window,\n\
102`pc' for a direct-write MS-DOS frame.\n\
ff11dfa1 103Also see `live-frame-p'.")
f9898cc6
JB
104 (object)
105 Lisp_Object object;
dc6f92b8 106{
e35d291d 107 if (!FRAMEP (object))
dc6f92b8 108 return Qnil;
ff11dfa1 109 switch (XFRAME (object)->output_method)
dc6f92b8
JB
110 {
111 case output_termcap:
112 return Qt;
113 case output_x_window:
fd0c2bd1 114 return Qx;
87485d6f 115 /* The `pc' case is in the Fframep below. */
dc6f92b8
JB
116 default:
117 abort ();
118 }
119}
120
dbc4e1c1 121DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
122 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
123Value is nil if OBJECT is not a live frame. If object is a live\n\
124frame, the return value indicates what sort of output device it is\n\
125displayed on. Value is t for a termcap frame (a character-only\n\
126terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
127 (object)
128 Lisp_Object object;
129{
ff11dfa1
JB
130 return ((FRAMEP (object)
131 && FRAME_LIVE_P (XFRAME (object)))
132 ? Fframep (object)
f9898cc6
JB
133 : Qnil);
134}
135
ff11dfa1
JB
136struct frame *
137make_frame (mini_p)
dc6f92b8
JB
138 int mini_p;
139{
ff11dfa1
JB
140 Lisp_Object frame;
141 register struct frame *f;
dc6f92b8
JB
142 register Lisp_Object root_window;
143 register Lisp_Object mini_window;
36af7d69
KH
144 register struct Lisp_Vector *vec;
145 int i;
146
147 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
148 for (i = 0; i < VECSIZE (struct frame); i++)
149 XSETFASTINT (vec->contents[i], 0);
150 vec->size = VECSIZE (struct frame);
151 f = (struct frame *)vec;
152 XSETFRAME (frame, f);
ff11dfa1
JB
153
154 f->cursor_x = 0;
155 f->cursor_y = 0;
156 f->current_glyphs = 0;
157 f->desired_glyphs = 0;
158 f->visible = 0;
323405de 159 f->async_visible = 0;
ff11dfa1
JB
160 f->display.nothing = 0;
161 f->iconified = 0;
323405de 162 f->async_iconified = 0;
ff11dfa1
JB
163 f->wants_modeline = 1;
164 f->auto_raise = 0;
165 f->auto_lower = 0;
166 f->no_split = 0;
167 f->garbaged = 0;
168 f->has_minibuffer = mini_p;
a42e9724 169 f->focus_frame = Qnil;
804518aa 170 f->explicit_name = 0;
fd2777e0
JB
171 f->can_have_scroll_bars = 0;
172 f->has_vertical_scroll_bars = 0;
ff11dfa1 173 f->param_alist = Qnil;
fd2777e0
JB
174 f->scroll_bars = Qnil;
175 f->condemned_scroll_bars = Qnil;
306cc902 176 f->face_alist = Qnil;
9dd935ee 177 f->menu_bar_items = Qnil;
c8b8e7e3
RS
178 f->menu_bar_vector = Qnil;
179 f->menu_bar_items_used = 0;
dc6f92b8 180
cc38027b 181 root_window = make_window ();
dc6f92b8
JB
182 if (mini_p)
183 {
cc38027b 184 mini_window = make_window ();
dc6f92b8
JB
185 XWINDOW (root_window)->next = mini_window;
186 XWINDOW (mini_window)->prev = root_window;
187 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
188 XWINDOW (mini_window)->frame = frame;
189 f->minibuffer_window = mini_window;
dc6f92b8
JB
190 }
191 else
192 {
193 mini_window = Qnil;
194 XWINDOW (root_window)->next = Qnil;
ff11dfa1 195 f->minibuffer_window = Qnil;
dc6f92b8
JB
196 }
197
ff11dfa1 198 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
199
200 /* 10 is arbitrary,
201 just so that there is "something there."
ff11dfa1 202 Correct size will be set up later with change_frame_size. */
dc6f92b8 203
ff11dfa1
JB
204 f->width = 10;
205 f->height = 10;
dc6f92b8 206
f4e93c40
KH
207 XSETFASTINT (XWINDOW (root_window)->width, 10);
208 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
dc6f92b8
JB
209
210 if (mini_p)
211 {
f4e93c40
KH
212 XSETFASTINT (XWINDOW (mini_window)->width, 10);
213 XSETFASTINT (XWINDOW (mini_window)->top, 9);
214 XSETFASTINT (XWINDOW (mini_window)->height, 1);
dc6f92b8
JB
215 }
216
ff11dfa1 217 /* Choose a buffer for the frame's root window. */
5bce042c
JB
218 {
219 Lisp_Object buf;
220
221 XWINDOW (root_window)->buffer = Qt;
222 buf = Fcurrent_buffer ();
223 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
224 a space), try to find another one. */
225 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 226 buf = Fother_buffer (buf, Qnil);
5bce042c
JB
227 Fset_window_buffer (root_window, buf);
228 }
229
dc6f92b8
JB
230 if (mini_p)
231 {
232 XWINDOW (mini_window)->buffer = Qt;
233 Fset_window_buffer (mini_window,
265a9e55 234 (NILP (Vminibuffer_list)
dc6f92b8
JB
235 ? get_minibuffer (0)
236 : Fcar (Vminibuffer_list)));
237 }
238
ff11dfa1
JB
239 f->root_window = root_window;
240 f->selected_window = root_window;
d5e7c279
JB
241 /* Make sure this window seems more recently used than
242 a newly-created, never-selected window. */
f4e93c40 243 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
dc6f92b8 244
ff11dfa1 245 return f;
dc6f92b8
JB
246}
247\f
ff11dfa1 248/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
249 MINI_WINDOW is the minibuffer window to use. nil means use the
250 default (the global minibuffer). */
251
ff11dfa1
JB
252struct frame *
253make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
254 register Lisp_Object mini_window;
255{
ff11dfa1 256 register struct frame *f;
dc6f92b8
JB
257
258 /* Choose the minibuffer window to use. */
265a9e55 259 if (NILP (mini_window))
dc6f92b8 260 {
e35d291d 261 if (!FRAMEP (Vdefault_minibuffer_frame))
ff11dfa1
JB
262 error ("default-minibuffer-frame must be set when creating minibufferless frames");
263 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
264 error ("default-minibuffer-frame must be a live frame");
265 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
266 }
267 else
268 {
774910eb 269 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8
JB
270 }
271
ff11dfa1
JB
272 /* Make a frame containing just a root window. */
273 f = make_frame (0);
dc6f92b8
JB
274
275 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 276 f->minibuffer_window = mini_window;
dc6f92b8 277 Fset_window_buffer (mini_window,
265a9e55 278 (NILP (Vminibuffer_list)
dc6f92b8
JB
279 ? get_minibuffer (0)
280 : Fcar (Vminibuffer_list)));
ff11dfa1 281 return f;
dc6f92b8
JB
282}
283
ff11dfa1 284/* Make a frame containing only a minibuffer window. */
dc6f92b8 285
ff11dfa1
JB
286struct frame *
287make_minibuffer_frame ()
dc6f92b8 288{
ff11dfa1 289 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 290
ff11dfa1 291 register struct frame *f = make_frame (0);
dc6f92b8 292 register Lisp_Object mini_window;
ff11dfa1 293 register Lisp_Object frame;
dc6f92b8 294
2d80a27a 295 XSETFRAME (frame, f);
dc6f92b8 296
804518aa 297 f->auto_raise = 0;
ff11dfa1
JB
298 f->auto_lower = 0;
299 f->no_split = 1;
300 f->wants_modeline = 0;
301 f->has_minibuffer = 1;
dc6f92b8
JB
302
303 /* Now label the root window as also being the minibuffer.
304 Avoid infinite looping on the window chain by marking next pointer
305 as nil. */
306
ff11dfa1 307 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
308 XWINDOW (mini_window)->mini_p = Qt;
309 XWINDOW (mini_window)->next = Qnil;
804518aa 310 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 311 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
312
313 /* Put the proper buffer in that window. */
314
315 Fset_window_buffer (mini_window,
265a9e55 316 (NILP (Vminibuffer_list)
dc6f92b8
JB
317 ? get_minibuffer (0)
318 : Fcar (Vminibuffer_list)));
ff11dfa1 319 return f;
dc6f92b8
JB
320}
321\f
ff11dfa1 322/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 323
ff11dfa1
JB
324struct frame *
325make_terminal_frame ()
dc6f92b8 326{
ff11dfa1 327 register struct frame *f;
d063751a 328 Lisp_Object frame;
ff11dfa1
JB
329
330 Vframe_list = Qnil;
331 f = make_frame (1);
d063751a 332
2d80a27a 333 XSETFRAME (frame, f);
d063751a
RS
334 Vframe_list = Fcons (frame, Vframe_list);
335
ff11dfa1 336 f->name = build_string ("terminal");
a42e9724 337 FRAME_SET_VISIBLE (f, 1);
ff11dfa1 338 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
2d80a27a 339 XSETFRAME (Vterminal_frame, f);
ff11dfa1 340 return f;
dc6f92b8
JB
341}
342\f
0aed85f4
KH
343static Lisp_Object
344do_switch_frame (frame, no_enter, track)
ff11dfa1 345 Lisp_Object frame, no_enter;
0aed85f4 346 int track;
dc6f92b8 347{
2f0b07e0
JB
348 /* If FRAME is a switch-frame event, extract the frame we should
349 switch to. */
350 if (CONSP (frame)
351 && EQ (XCONS (frame)->car, Qswitch_frame)
352 && CONSP (XCONS (frame)->cdr))
353 frame = XCONS (XCONS (frame)->cdr)->car;
354
09907c3a
KH
355 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
356 a switch-frame event to arrive after a frame is no longer live,
357 especially when deleting the initial frame during startup. */
358 CHECK_FRAME (frame, 0);
359 if (! FRAME_LIVE_P (XFRAME (frame)))
360 return Qnil;
dc6f92b8 361
ff11dfa1
JB
362 if (selected_frame == XFRAME (frame))
363 return frame;
dc6f92b8 364
0aed85f4
KH
365 /* This is too greedy; it causes inappropriate focus redirection
366 that's hard to get rid of. */
367#if 0
a42e9724
JB
368 /* If a frame's focus has been redirected toward the currently
369 selected frame, we should change the redirection to point to the
370 newly selected frame. This means that if the focus is redirected
371 from a minibufferless frame to a surrogate minibuffer frame, we
372 can use `other-window' to switch between all the frames using
373 that minibuffer frame, and the focus redirection will follow us
374 around. */
0aed85f4
KH
375 if (track)
376 {
377 Lisp_Object tail;
a42e9724 378
0aed85f4
KH
379 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
380 {
381 Lisp_Object focus;
a42e9724 382
e35d291d 383 if (!FRAMEP (XCONS (tail)->car))
0aed85f4 384 abort ();
a42e9724 385
0aed85f4 386 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
a42e9724 387
e35d291d 388 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
0aed85f4
KH
389 Fredirect_frame_focus (XCONS (tail)->car, frame);
390 }
391 }
392#else /* ! 0 */
393 /* Instead, apply it only to the frame we're pointing to. */
394#ifdef HAVE_X_WINDOWS
395 if (track)
396 {
397 Lisp_Object focus, xfocus;
398
399 xfocus = x_get_focus_frame ();
400 if (FRAMEP (xfocus))
401 {
402 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
403 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
404 Fredirect_frame_focus (xfocus, frame);
405 }
406 }
407#endif /* HAVE_X_WINDOWS */
408#endif /* ! 0 */
a42e9724 409
ff11dfa1
JB
410 selected_frame = XFRAME (frame);
411 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
412 last_nonminibuf_frame = selected_frame;
d5e7c279 413
ff11dfa1 414 Fselect_window (XFRAME (frame)->selected_window);
ff11dfa1 415 choose_minibuf_frame ();
dc6f92b8 416
074577b8 417 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 418 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
419 before you take it out, make sure that evaluating something like
420 (select-window (frame-root-window (new-frame))) doesn't end up
421 with your typing being interpreted in the new frame instead of
422 the one you're actually typing in. */
fd2777e0 423 internal_last_event_frame = Qnil;
074577b8 424
ff11dfa1 425 return frame;
dc6f92b8
JB
426}
427
0aed85f4
KH
428DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
429 "Select the frame FRAME.\n\
430Subsequent editing commands apply to its selected window.\n\
431The selection of FRAME lasts until the next time the user does\n\
432something to select a different frame, or until the next time this\n\
433function is called.")
434 (frame, no_enter)
435 Lisp_Object frame, no_enter;
436{
437 return do_switch_frame (frame, no_enter, 1);
438}
439
440
441DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
442 "Handle a switch-frame event EVENT.\n\
443Switch-frame events are usually bound to this function.\n\
444A switch-frame event tells Emacs that the window manager has requested\n\
445that the user's events be directed to the frame mentioned in the event.\n\
446This function selects the selected window of the frame of EVENT.\n\
447\n\
448If EVENT is frame object, handle it as if it were a switch-frame event\n\
449to that frame.")
450 (frame, no_enter)
451 Lisp_Object frame, no_enter;
452{
453 return do_switch_frame (frame, no_enter, 0);
454}
455
456
ff11dfa1
JB
457DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
458 "Return the frame that is now selected.")
dc6f92b8
JB
459 ()
460{
461 Lisp_Object tem;
2d80a27a 462 XSETFRAME (tem, selected_frame);
dc6f92b8
JB
463 return tem;
464}
4a7cfafc 465\f
ff11dfa1
JB
466DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
467 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
468 (window)
469 Lisp_Object window;
470{
774910eb 471 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 472 return XWINDOW (window)->frame;
dc6f92b8
JB
473}
474
ba32f2db
KH
475DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
476 "Returns the topmost, leftmost window of FRAME.\n\
477If omitted, FRAME defaults to the currently selected frame.")
478 (frame)
479 Lisp_Object frame;
480{
481 Lisp_Object w;
482
483 if (NILP (frame))
484 w = selected_frame->root_window;
485 else
486 {
487 CHECK_LIVE_FRAME (frame, 0);
488 w = XFRAME (frame)->root_window;
489 }
490 while (NILP (XWINDOW (w)->buffer))
491 {
492 if (! NILP (XWINDOW (w)->hchild))
493 w = XWINDOW (w)->hchild;
494 else if (! NILP (XWINDOW (w)->vchild))
495 w = XWINDOW (w)->vchild;
496 else
497 abort ();
498 }
499 return w;
500}
501
ff11dfa1 502DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
503 "Returns the root-window of FRAME.\n\
504If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
505 (frame)
506 Lisp_Object frame;
dc6f92b8 507{
ff11dfa1 508 if (NILP (frame))
2d80a27a 509 XSETFRAME (frame, selected_frame);
f9898cc6 510 else
ff11dfa1 511 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 512
ff11dfa1 513 return XFRAME (frame)->root_window;
dc6f92b8
JB
514}
515
ff11dfa1
JB
516DEFUN ("frame-selected-window", Fframe_selected_window,
517 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
518 "Return the selected window of frame object FRAME.\n\
519If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
520 (frame)
521 Lisp_Object frame;
dc6f92b8 522{
ff11dfa1 523 if (NILP (frame))
2d80a27a 524 XSETFRAME (frame, selected_frame);
f9898cc6 525 else
ff11dfa1 526 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 527
ff11dfa1 528 return XFRAME (frame)->selected_window;
dc6f92b8
JB
529}
530
4a7cfafc
RS
531DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
532 Sset_frame_selected_window, 2, 2, 0,
533 "Set the selected window of frame object FRAME to WINDOW.\n\
534If FRAME is nil, the selected frame is used.\n\
535If FRAME is the selected frame, this makes WINDOW the selected window.")
536 (frame, window)
537 Lisp_Object frame, window;
538{
539 if (NILP (frame))
2d80a27a 540 XSETFRAME (frame, selected_frame);
4a7cfafc
RS
541 else
542 CHECK_LIVE_FRAME (frame, 0);
543
544 CHECK_LIVE_WINDOW (window, 1);
545
546 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
547 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
548
549 if (XFRAME (frame) == selected_frame)
550 return Fselect_window (window);
551
552 return XFRAME (frame)->selected_window = window;
553}
554\f
ff11dfa1 555DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 556 0, 0, 0,
ff11dfa1 557 "Return a list of all frames.")
dc6f92b8
JB
558 ()
559{
ff11dfa1 560 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
561}
562
ff11dfa1 563/* Return the next frame in the frame list after FRAME.
ff11dfa1 564 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
565 If MINIBUF is a window, include only its own frame
566 and any frame now using that window as the minibuffer.
f7af3f7b 567 If MINIBUF is `visible', include all visible frames.
a9986780 568 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
569 Otherwise, include all frames. */
570
dc6f92b8 571Lisp_Object
ff11dfa1
JB
572next_frame (frame, minibuf)
573 Lisp_Object frame;
f9898cc6 574 Lisp_Object minibuf;
dc6f92b8
JB
575{
576 Lisp_Object tail;
577 int passed = 0;
578
ff11dfa1
JB
579 /* There must always be at least one frame in Vframe_list. */
580 if (! CONSP (Vframe_list))
f9898cc6
JB
581 abort ();
582
dbc4e1c1
JB
583 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
584 forever. Forestall that. */
585 CHECK_LIVE_FRAME (frame, 0);
586
dc6f92b8 587 while (1)
ff11dfa1 588 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 589 {
ab9f008d 590 Lisp_Object f;
d06a8a56 591
ab9f008d 592 f = XCONS (tail)->car;
dc6f92b8 593 if (passed)
d5e7c279 594 {
d06a8a56
JB
595 /* Decide whether this frame is eligible to be returned. */
596
597 /* If we've looped all the way around without finding any
598 eligible frames, return the original frame. */
599 if (EQ (f, frame))
600 return f;
601
602 /* Let minibuf decide if this frame is acceptable. */
603 if (NILP (minibuf))
604 {
605 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
606 return f;
607 }
f7af3f7b
RS
608 else if (EQ (minibuf, Qvisible))
609 {
610 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
611 if (FRAME_VISIBLE_P (XFRAME (f)))
612 return f;
613 }
a9986780
RS
614 else if (XFASTINT (minibuf) == 0)
615 {
616 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
617 if (FRAME_VISIBLE_P (XFRAME (f))
618 || FRAME_ICONIFIED_P (XFRAME (f)))
619 return f;
620 }
f7af3f7b 621 else if (WINDOWP (minibuf))
d06a8a56 622 {
a9986780
RS
623 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
624 /* Check that F either is, or has forwarded its focus to,
625 MINIBUF's frame. */
626 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
627 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
628 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
629 return f;
630 }
631 else
ff11dfa1 632 return f;
d5e7c279 633 }
dc6f92b8 634
d06a8a56 635 if (EQ (frame, f))
dc6f92b8
JB
636 passed++;
637 }
638}
639
ff11dfa1 640/* Return the previous frame in the frame list before FRAME.
ff11dfa1 641 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
642 If MINIBUF is a window, include only its own frame
643 and any frame now using that window as the minibuffer.
f7af3f7b 644 If MINIBUF is `visible', include all visible frames.
a9986780 645 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
646 Otherwise, include all frames. */
647
dc6f92b8 648Lisp_Object
ff11dfa1
JB
649prev_frame (frame, minibuf)
650 Lisp_Object frame;
f9898cc6 651 Lisp_Object minibuf;
dc6f92b8
JB
652{
653 Lisp_Object tail;
654 Lisp_Object prev;
655
ff11dfa1
JB
656 /* There must always be at least one frame in Vframe_list. */
657 if (! CONSP (Vframe_list))
f9898cc6
JB
658 abort ();
659
dc6f92b8 660 prev = Qnil;
d06a8a56 661 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 662 {
ab9f008d 663 Lisp_Object f;
f9898cc6 664
ab9f008d 665 f = XCONS (tail)->car;
e35d291d 666 if (!FRAMEP (f))
d06a8a56 667 abort ();
f9898cc6 668
d06a8a56
JB
669 if (EQ (frame, f) && !NILP (prev))
670 return prev;
f9898cc6 671
d06a8a56
JB
672 /* Decide whether this frame is eligible to be returned,
673 according to minibuf. */
674 if (NILP (minibuf))
675 {
676 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
677 prev = f;
f9898cc6 678 }
aea9f59e 679 else if (WINDOWP (minibuf))
d06a8a56 680 {
a9986780
RS
681 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
682 /* Check that F either is, or has forwarded its focus to,
683 MINIBUF's frame. */
684 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
685 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
686 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
687 prev = f;
688 }
f7af3f7b
RS
689 else if (EQ (minibuf, Qvisible))
690 {
691 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
692 if (FRAME_VISIBLE_P (XFRAME (f)))
693 prev = f;
694 }
aea9f59e 695 else if (XFASTINT (minibuf) == 0)
a9986780
RS
696 {
697 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
698 if (FRAME_VISIBLE_P (XFRAME (f))
699 || FRAME_ICONIFIED_P (XFRAME (f)))
700 prev = f;
701 }
d06a8a56
JB
702 else
703 prev = f;
f9898cc6 704 }
d06a8a56
JB
705
706 /* We've scanned the entire list. */
707 if (NILP (prev))
708 /* We went through the whole frame list without finding a single
709 acceptable frame. Return the original frame. */
710 return frame;
711 else
712 /* There were no acceptable frames in the list before FRAME; otherwise,
713 we would have returned directly from the loop. Since PREV is the last
714 acceptable frame in the list, return it. */
715 return prev;
dc6f92b8
JB
716}
717
ef2c57ac 718
ff11dfa1
JB
719DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
720 "Return the next frame in the frame list after FRAME.\n\
a42e9724 721By default, skip minibuffer-only frames.\n\
d06a8a56 722If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 723If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
a9986780
RS
724If MINIBUF is a window, include only its own frame\n\
725and any frame now using that window as the minibuffer.\n\
f7af3f7b 726If MINIFRAME is `visible', include all visible frames.\n\
a9986780 727If MINIBUF is 0, include all visible and iconified frames.\n\
f7af3f7b 728Otherwise, include all frames.")
ff11dfa1 729 (frame, miniframe)
8693ca83 730 Lisp_Object frame, miniframe;
dc6f92b8
JB
731{
732 Lisp_Object tail;
733
ff11dfa1 734 if (NILP (frame))
2d80a27a 735 XSETFRAME (frame, selected_frame);
f9898cc6 736 else
ff11dfa1 737 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 738
ff11dfa1 739 return next_frame (frame, miniframe);
dc6f92b8 740}
dbc4e1c1 741
ef2c57ac
RM
742DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
743 "Return the previous frame in the frame list before FRAME.\n\
744By default, skip minibuffer-only frames.\n\
745If omitted, FRAME defaults to the selected frame.\n\
746If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
a9986780
RS
747If MINIBUF is a window, include only its own frame\n\
748and any frame now using that window as the minibuffer.\n\
f7af3f7b 749If MINIFRAME is `visible', include all visible frames.\n\
a9986780 750If MINIBUF is 0, include all visible and iconified frames.\n\
f7af3f7b 751Otherwise, include all frames.")
ef2c57ac
RM
752 (frame, miniframe)
753 Lisp_Object frame, miniframe;
754{
755 Lisp_Object tail;
756
757 if (NILP (frame))
2d80a27a 758 XSETFRAME (frame, selected_frame);
ef2c57ac
RM
759 else
760 CHECK_LIVE_FRAME (frame, 0);
761
762 return prev_frame (frame, miniframe);
763}
dc6f92b8 764\f
808c0f20
RS
765/* Return 1 if it is ok to delete frame F;
766 0 if all frames aside from F are invisible.
767 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 768
d56b45eb 769int
808c0f20
RS
770other_visible_frames (f)
771 FRAME_PTR f;
772{
773 /* We know the selected frame is visible,
774 so if F is some other frame, it can't be the sole visible one. */
775 if (f == selected_frame)
c08c95c7
RS
776 {
777 Lisp_Object frames;
778 int count = 0;
779
780 for (frames = Vframe_list;
781 CONSP (frames);
782 frames = XCONS (frames)->cdr)
783 {
ab9f008d 784 Lisp_Object this;
c08c95c7 785
ab9f008d 786 this = XCONS (frames)->car;
808c0f20
RS
787 /* Verify that the frame's window still exists
788 and we can still talk to it. And note any recent change
789 in visibility. */
5e7b7c5b
RS
790#ifdef HAVE_X_WINDOWS
791 if (FRAME_X_P (XFRAME (this)))
792 {
b0509a40 793 x_sync (XFRAME (this));
5e7b7c5b
RS
794 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
795 }
796#endif
797
c08c95c7
RS
798 if (FRAME_VISIBLE_P (XFRAME (this))
799 || FRAME_ICONIFIED_P (XFRAME (this))
800 /* Allow deleting the terminal frame when at least
801 one X frame exists! */
9fbb139c 802 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
c08c95c7
RS
803 count++;
804 }
808c0f20 805 return count > 1;
c08c95c7 806 }
808c0f20
RS
807 return 1;
808}
809
810DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
811 "Delete FRAME, permanently eliminating it from use.\n\
812If omitted, FRAME defaults to the selected frame.\n\
813A frame may not be deleted if its minibuffer is used by other frames.\n\
814Normally, you may not delete a frame if all other frames are invisible,\n\
815but if the second optional argument FORCE is non-nil, you may do so.")
816 (frame, force)
817 Lisp_Object frame, force;
818{
819 struct frame *f;
820
821 if (EQ (frame, Qnil))
822 {
823 f = selected_frame;
2d80a27a 824 XSETFRAME (frame, f);
808c0f20
RS
825 }
826 else
827 {
828 CHECK_FRAME (frame, 0);
829 f = XFRAME (frame);
830 }
831
832 if (! FRAME_LIVE_P (f))
833 return Qnil;
834
835 if (NILP (force) && !other_visible_frames (f))
836 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 837
ff11dfa1
JB
838 /* Does this frame have a minibuffer, and is it the surrogate
839 minibuffer for any other frame? */
fd0c2bd1 840 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 841 {
ff11dfa1 842 Lisp_Object frames;
1113d9db 843
ff11dfa1
JB
844 for (frames = Vframe_list;
845 CONSP (frames);
846 frames = XCONS (frames)->cdr)
1113d9db 847 {
7a8cc307
RS
848 Lisp_Object this;
849 this = XCONS (frames)->car;
1113d9db 850
ff11dfa1
JB
851 if (! EQ (this, frame)
852 && EQ (frame,
7a8cc307
RS
853 WINDOW_FRAME (XWINDOW
854 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 855 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 856 }
dc6f92b8
JB
857 }
858
ff11dfa1
JB
859 /* Don't let the frame remain selected. */
860 if (f == selected_frame)
0f85737c 861 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
dc6f92b8 862
ff11dfa1
JB
863 /* Don't allow minibuf_window to remain on a deleted frame. */
864 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 865 {
ff11dfa1 866 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 867 XWINDOW (minibuf_window)->buffer);
ff11dfa1 868 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
869 }
870
bb2a0a65
RS
871 /* Clear any X selections for this frame. */
872#ifdef HAVE_X_WINDOWS
873 if (FRAME_X_P (f))
874 x_clear_frame_selections (f);
875#endif
876
4a88b3b0
JB
877 /* Mark all the windows that used to be on FRAME as deleted, and then
878 remove the reference to them. */
879 delete_all_subwindows (XWINDOW (f->root_window));
880 f->root_window = Qnil;
881
ff11dfa1 882 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 883 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 884
d2bee99e
RS
885 if (FRAME_CURRENT_GLYPHS (f))
886 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
887 if (FRAME_DESIRED_GLYPHS (f))
888 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
889 if (FRAME_TEMP_GLYPHS (f))
890 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
891 if (FRAME_INSERT_COST (f))
892 free (FRAME_INSERT_COST (f));
893 if (FRAME_DELETEN_COST (f))
09d1d7e2 894 free (FRAME_DELETEN_COST (f));
d2bee99e 895 if (FRAME_INSERTN_COST (f))
09d1d7e2 896 free (FRAME_INSERTN_COST (f));
d2bee99e 897 if (FRAME_DELETE_COST (f))
09d1d7e2 898 free (FRAME_DELETE_COST (f));
d2bee99e 899
8678b9cc
JB
900 /* Since some events are handled at the interrupt level, we may get
901 an event for f at any time; if we zero out the frame's display
902 now, then we may trip up the event-handling code. Instead, we'll
903 promise that the display of the frame must be valid until we have
904 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
905
906 /* I think this should be done with a hook. */
d5e7c279 907#ifdef HAVE_X_WINDOWS
fd0c2bd1 908 if (FRAME_X_P (f))
8678b9cc 909 x_destroy_window (f);
d5e7c279
JB
910#endif
911
8678b9cc
JB
912 f->display.nothing = 0;
913
ff11dfa1 914 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 915 another one. */
ff11dfa1 916 if (f == last_nonminibuf_frame)
d5e7c279 917 {
ff11dfa1 918 Lisp_Object frames;
1113d9db 919
ff11dfa1 920 last_nonminibuf_frame = 0;
d5e7c279 921
ff11dfa1
JB
922 for (frames = Vframe_list;
923 CONSP (frames);
924 frames = XCONS (frames)->cdr)
d5e7c279 925 {
ff11dfa1
JB
926 f = XFRAME (XCONS (frames)->car);
927 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 928 {
ff11dfa1 929 last_nonminibuf_frame = f;
d5e7c279
JB
930 break;
931 }
932 }
933 }
dc6f92b8 934
ff11dfa1
JB
935 /* If we've deleted Vdefault_minibuffer_frame, try to find another
936 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 937 with other windows. */
ff11dfa1 938 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 939 {
ff11dfa1 940 Lisp_Object frames;
1113d9db 941
ff11dfa1 942 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 943 Lisp_Object frame_with_minibuf;
1113d9db 944
ab9f008d 945 frame_with_minibuf = Qnil;
ff11dfa1
JB
946 for (frames = Vframe_list;
947 CONSP (frames);
948 frames = XCONS (frames)->cdr)
1113d9db 949 {
ab9f008d 950 Lisp_Object this;
1113d9db 951
ab9f008d 952 this = XCONS (frames)->car;
e35d291d 953 if (!FRAMEP (this))
1113d9db 954 abort ();
ff11dfa1 955 f = XFRAME (this);
1113d9db 956
fd0c2bd1 957 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 958 {
ff11dfa1
JB
959 frame_with_minibuf = this;
960 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
961 break;
962 }
963 }
964
ff11dfa1
JB
965 /* We know that there must be some frame with a minibuffer out
966 there. If this were not true, all of the frames present
1113d9db 967 would have to be minibufferless, which implies that at some
ff11dfa1 968 point their minibuffer frames must have been deleted, but
1113d9db 969 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
970 minibuffer frames. */
971 if (NILP (frame_with_minibuf))
1113d9db
JB
972 abort ();
973
ff11dfa1 974 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
975 }
976
dc6f92b8
JB
977 return Qnil;
978}
979\f
980/* Return mouse position in character cell units. */
981
f9898cc6 982DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 983 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
984The position is given in character cells, where (0, 0) is the\n\
985upper-left corner.\n\
f9898cc6 986If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 987to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
988and nil for X and Y.")
989 ()
dc6f92b8 990{
ff11dfa1 991 FRAME_PTR f;
dbc4e1c1 992 Lisp_Object lispy_dummy;
fd2777e0 993 enum scroll_bar_part party_dummy;
dbc4e1c1 994 Lisp_Object x, y;
5384466a 995 int col, row;
dbc4e1c1 996 unsigned long long_dummy;
dc6f92b8 997
c5074d8c
RS
998 f = selected_frame;
999 x = y = Qnil;
1000
1001 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1002 if (mouse_position_hook)
dbc4e1c1
JB
1003 (*mouse_position_hook) (&f,
1004 &lispy_dummy, &party_dummy,
1005 &x, &y,
1006 &long_dummy);
76db7eb4
KH
1007 if (! NILP (x))
1008 {
1009 col = XINT (x);
1010 row = XINT (y);
6a6d921c 1011 pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
76db7eb4
KH
1012 XSETINT (x, col);
1013 XSETINT (y, row);
1014 }
2d80a27a 1015 XSETFRAME (lispy_dummy, f);
c5074d8c 1016 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1017}
1018
152e6c70
RS
1019DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1020 Smouse_pixel_position, 0, 0, 0,
1021 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1022The position is given in pixel units, where (0, 0) is the\n\
1023upper-left corner.\n\
1024If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1025to read the mouse position, it returns the selected frame for FRAME\n\
1026and nil for X and Y.")
1027 ()
1028{
1029 FRAME_PTR f;
1030 Lisp_Object lispy_dummy;
1031 enum scroll_bar_part party_dummy;
1032 Lisp_Object x, y;
1033 int col, row;
1034 unsigned long long_dummy;
1035
1036 f = selected_frame;
1037 x = y = Qnil;
1038
1039 /* It's okay for the hook to refrain from storing anything. */
1040 if (mouse_position_hook)
1041 (*mouse_position_hook) (&f,
1042 &lispy_dummy, &party_dummy,
1043 &x, &y,
1044 &long_dummy);
2d80a27a 1045 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1046 return Fcons (lispy_dummy, Fcons (x, y));
1047}
1048
dc6f92b8 1049DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1050 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
152e6c70
RS
1051WARNING: If you use this under X windows,\n\
1052you should call `unfocus-frame' afterwards.")
ff11dfa1
JB
1053 (frame, x, y)
1054 Lisp_Object frame, x, y;
dc6f92b8 1055{
ff11dfa1 1056 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1057 CHECK_NUMBER (x, 2);
1058 CHECK_NUMBER (y, 1);
1059
dbc4e1c1 1060 /* I think this should be done with a hook. */
dc6f92b8 1061#ifdef HAVE_X_WINDOWS
fd0c2bd1 1062 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 1063 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1064 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
1065#endif
1066
1067 return Qnil;
1068}
152e6c70
RS
1069
1070DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1071 Sset_mouse_pixel_position, 3, 3, 0,
1072 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1073WARNING: If you use this under X windows,\n\
1074you should call `unfocus-frame' afterwards.")
1075 (frame, x, y)
1076 Lisp_Object frame, x, y;
1077{
1078 CHECK_LIVE_FRAME (frame, 0);
1079 CHECK_NUMBER (x, 2);
1080 CHECK_NUMBER (y, 1);
1081
1082 /* I think this should be done with a hook. */
1083#ifdef HAVE_X_WINDOWS
1084 if (FRAME_X_P (XFRAME (frame)))
1085 /* Warping the mouse will cause enternotify and focus events. */
1086 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1087#endif
1088
1089 return Qnil;
1090}
dc6f92b8 1091\f
ff11dfa1 1092DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1093 0, 1, "",
ff11dfa1 1094 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1095If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1096 (frame)
1097 Lisp_Object frame;
dc6f92b8 1098{
1aa66088 1099 if (NILP (frame))
2d80a27a 1100 XSETFRAME (frame, selected_frame);
1aa66088 1101
ff11dfa1 1102 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1103
dbc4e1c1 1104 /* I think this should be done with a hook. */
fd0c2bd1
JB
1105#ifdef HAVE_X_WINDOWS
1106 if (FRAME_X_P (XFRAME (frame)))
02ff9dd5
RS
1107 {
1108 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1109 x_make_frame_visible (XFRAME (frame));
1110 }
fd0c2bd1 1111#endif
dc6f92b8 1112
565620a5
RS
1113 /* Make menu bar update for the Buffers and Frams menus. */
1114 windows_or_buffers_changed++;
1115
ff11dfa1 1116 return frame;
dc6f92b8
JB
1117}
1118
ff11dfa1 1119DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1120 0, 2, "",
8693ca83 1121 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1122If omitted, FRAME defaults to the currently selected frame.\n\
1123Normally you may not make FRAME invisible if all other frames are invisible,\n\
1124but if the second optional argument FORCE is non-nil, you may do so.")
1125 (frame, force)
1126 Lisp_Object frame, force;
dc6f92b8 1127{
1aa66088 1128 if (NILP (frame))
2d80a27a 1129 XSETFRAME (frame, selected_frame);
1aa66088 1130
ff11dfa1 1131 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1132
808c0f20
RS
1133 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1134 error ("Attempt to make invisible the sole visible or iconified frame");
1135
3d378fdf 1136#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1137 /* Don't let the frame remain selected. */
1138 if (XFRAME (frame) == selected_frame)
1139 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1140#endif
9c394f17
RS
1141
1142 /* Don't allow minibuf_window to remain on a deleted frame. */
1143 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1144 {
1145 Fset_window_buffer (selected_frame->minibuffer_window,
1146 XWINDOW (minibuf_window)->buffer);
1147 minibuf_window = selected_frame->minibuffer_window;
1148 }
1149
dbc4e1c1 1150 /* I think this should be done with a hook. */
fd0c2bd1
JB
1151#ifdef HAVE_X_WINDOWS
1152 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 1153 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1154#endif
dc6f92b8 1155
565620a5
RS
1156 /* Make menu bar update for the Buffers and Frams menus. */
1157 windows_or_buffers_changed++;
1158
dc6f92b8
JB
1159 return Qnil;
1160}
1161
ff11dfa1 1162DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1163 0, 1, "",
8693ca83
JB
1164 "Make the frame FRAME into an icon.\n\
1165If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1166 (frame)
1167 Lisp_Object frame;
dc6f92b8 1168{
1aa66088 1169 if (NILP (frame))
2d80a27a 1170 XSETFRAME (frame, selected_frame);
1aa66088 1171
ff11dfa1 1172 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1173
3d378fdf 1174#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1175 /* Don't let the frame remain selected. */
1176 if (XFRAME (frame) == selected_frame)
1177 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1178#endif
9c394f17
RS
1179
1180 /* Don't allow minibuf_window to remain on a deleted frame. */
1181 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1182 {
1183 Fset_window_buffer (selected_frame->minibuffer_window,
1184 XWINDOW (minibuf_window)->buffer);
1185 minibuf_window = selected_frame->minibuffer_window;
1186 }
1187
dbc4e1c1 1188 /* I think this should be done with a hook. */
fd0c2bd1
JB
1189#ifdef HAVE_X_WINDOWS
1190 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 1191 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1192#endif
dc6f92b8 1193
565620a5
RS
1194 /* Make menu bar update for the Buffers and Frams menus. */
1195 windows_or_buffers_changed++;
1196
dc6f92b8
JB
1197 return Qnil;
1198}
1199
ff11dfa1 1200DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1201 1, 1, 0,
ff11dfa1
JB
1202 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1203A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1204a window system, it may not show at all.\n\
fd0c2bd1 1205Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1206 (frame)
1207 Lisp_Object frame;
dc6f92b8 1208{
ff11dfa1 1209 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1210
5c044f55
RS
1211 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1212
a42e9724 1213 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1214 return Qt;
a42e9724 1215 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1216 return Qicon;
dc6f92b8
JB
1217 return Qnil;
1218}
1219
ff11dfa1 1220DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1221 0, 0, 0,
ff11dfa1 1222 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1223 ()
1224{
ff11dfa1
JB
1225 Lisp_Object tail, frame;
1226 struct frame *f;
dc6f92b8
JB
1227 Lisp_Object value;
1228
1229 value = Qnil;
ff11dfa1 1230 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1231 {
ff11dfa1 1232 frame = XCONS (tail)->car;
e35d291d 1233 if (!FRAMEP (frame))
dc6f92b8 1234 continue;
ff11dfa1 1235 f = XFRAME (frame);
a42e9724 1236 if (FRAME_VISIBLE_P (f))
ff11dfa1 1237 value = Fcons (frame, value);
dc6f92b8
JB
1238 }
1239 return value;
1240}
d5e7c279
JB
1241
1242
b49f5578 1243DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
dbc4e1c1
JB
1244 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1245If FRAME is invisible, make it visible.\n\
1246If Emacs is displaying on an ordinary terminal or some other device which\n\
1247doesn't support multiple overlapping frames, this function does nothing.")
1248 (frame)
1249 Lisp_Object frame;
1250{
1251 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1252
1253 /* Do like the documentation says. */
1254 Fmake_frame_visible (frame);
1255
dbc4e1c1
JB
1256 if (frame_raise_lower_hook)
1257 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1258
1259 return Qnil;
1260}
1261
b49f5578
JB
1262/* Should we have a corresponding function called Flower_Power? */
1263DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
dbc4e1c1
JB
1264 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1265If Emacs is displaying on an ordinary terminal or some other device which\n\
1266doesn't support multiple overlapping frames, this function does nothing.")
1267 (frame)
1268 Lisp_Object frame;
1269{
1270 CHECK_LIVE_FRAME (frame, 0);
1271
1272 if (frame_raise_lower_hook)
1273 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1274
1275 return Qnil;
1276}
1277
d5e7c279 1278\f
ff11dfa1 1279DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1280 1, 2, 0,
ff11dfa1 1281 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1282In other words, switch-frame events caused by events in FRAME will\n\
1283request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1284FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1285\n\
a42e9724 1286If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1287cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1288\n\
a42e9724
JB
1289Focus redirection is useful for temporarily redirecting keystrokes to\n\
1290a surrogate minibuffer frame when a frame doesn't have its own\n\
1291minibuffer window.\n\
d5e7c279 1292\n\
a42e9724
JB
1293A frame's focus redirection can be changed by select-frame. If frame\n\
1294FOO is selected, and then a different frame BAR is selected, any\n\
1295frames redirecting their focus to FOO are shifted to redirect their\n\
1296focus to BAR. This allows focus redirection to work properly when the\n\
1297user switches from one frame to another using `select-window'.\n\
1298\n\
1299This means that a frame whose focus is redirected to itself is treated\n\
1300differently from a frame whose focus is redirected to nil; the former\n\
1301is affected by select-frame, while the latter is not.\n\
1302\n\
1303The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1304 (frame, focus_frame)
1305 Lisp_Object frame, focus_frame;
d5e7c279 1306{
13144095
JB
1307 /* Note that we don't check for a live frame here. It's reasonable
1308 to redirect the focus of a frame you're about to delete, if you
1309 know what other frame should receive those keystrokes. */
1310 CHECK_FRAME (frame, 0);
f9898cc6 1311
a42e9724 1312 if (! NILP (focus_frame))
ff11dfa1 1313 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1314
ff11dfa1 1315 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1316
9c394f17
RS
1317 /* I think this should be done with a hook. */
1318#ifdef HAVE_X_WINDOWS
1319 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1320 && FRAME_X_P (XFRAME (focus_frame)))
1321 Ffocus_frame (focus_frame);
1322#endif
1323
ff11dfa1
JB
1324 if (frame_rehighlight_hook)
1325 (*frame_rehighlight_hook) ();
d5e7c279
JB
1326
1327 return Qnil;
1328}
1329
1330
ff11dfa1
JB
1331DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1332 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1333This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1334See `redirect-frame-focus'.")
1335 (frame)
1336 Lisp_Object frame;
d5e7c279 1337{
ff11dfa1 1338 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1339
ff11dfa1 1340 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1341}
1342
1343
dc6f92b8
JB
1344\f
1345Lisp_Object
ff11dfa1
JB
1346get_frame_param (frame, prop)
1347 register struct frame *frame;
dc6f92b8
JB
1348 Lisp_Object prop;
1349{
1350 register Lisp_Object tem;
1351
ff11dfa1 1352 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1353 if (EQ (tem, Qnil))
1354 return tem;
1355 return Fcdr (tem);
1356}
1357
1358void
fd0c2bd1 1359store_in_alist (alistptr, prop, val)
dc6f92b8 1360 Lisp_Object *alistptr, val;
fd0c2bd1 1361 Lisp_Object prop;
dc6f92b8
JB
1362{
1363 register Lisp_Object tem;
dc6f92b8 1364
dc6f92b8
JB
1365 tem = Fassq (prop, *alistptr);
1366 if (EQ (tem, Qnil))
1367 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1368 else
1369 Fsetcdr (tem, val);
1370}
1371
1372void
ff11dfa1
JB
1373store_frame_param (f, prop, val)
1374 struct frame *f;
dc6f92b8
JB
1375 Lisp_Object prop, val;
1376{
1377 register Lisp_Object tem;
1378
ff11dfa1 1379 tem = Fassq (prop, f->param_alist);
dc6f92b8 1380 if (EQ (tem, Qnil))
ff11dfa1 1381 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1382 else
1383 Fsetcdr (tem, val);
bc93c097 1384
e35d291d 1385 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1386 {
1387 if (! MINI_WINDOW_P (XWINDOW (val)))
1388 error ("Surrogate minibuffer windows must be minibuffer windows.");
1389
fd0c2bd1 1390 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1fb2d074 1391 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1392
1393 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1394 f->minibuffer_window = val;
bc93c097 1395 }
dc6f92b8
JB
1396}
1397
ff11dfa1
JB
1398DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1399 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1400It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1401The meaningful PARMs depend on the kind of frame.\n\
1402If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1403 (frame)
1404 Lisp_Object frame;
dc6f92b8
JB
1405{
1406 Lisp_Object alist;
f769f1b2 1407 FRAME_PTR f;
dc6f92b8 1408
ff11dfa1
JB
1409 if (EQ (frame, Qnil))
1410 f = selected_frame;
dc6f92b8
JB
1411 else
1412 {
ff11dfa1
JB
1413 CHECK_FRAME (frame, 0);
1414 f = XFRAME (frame);
dc6f92b8
JB
1415 }
1416
f769f1b2 1417 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1418 return Qnil;
1419
ff11dfa1 1420 alist = Fcopy_alist (f->param_alist);
fd0c2bd1 1421 store_in_alist (&alist, Qname, f->name);
f769f1b2
KH
1422 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
1423 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
1424 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1425 store_in_alist (&alist, Qminibuffer,
39acc701 1426 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1427 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1428 : FRAME_MINIBUF_WINDOW (f)));
1429 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fd0c2bd1 1430
dbc4e1c1 1431 /* I think this should be done with a hook. */
fd0c2bd1
JB
1432#ifdef HAVE_X_WINDOWS
1433 if (FRAME_X_P (f))
ff11dfa1 1434 x_report_frame_params (f, &alist);
b6dd20ed 1435 else
fd0c2bd1 1436#endif
16a3738c
KH
1437 {
1438 /* This ought to be correct in f->param_alist for an X frame. */
1439 Lisp_Object lines;
f4e93c40 1440 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1441 store_in_alist (&alist, Qmenu_bar_lines, lines);
1442 }
dc6f92b8
JB
1443 return alist;
1444}
1445
ff11dfa1
JB
1446DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1447 Smodify_frame_parameters, 2, 2, 0,
1448 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1449ALIST is an alist of parameters to change and their new values.\n\
1450Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1451The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1452 (frame, alist)
1453 Lisp_Object frame, alist;
dc6f92b8 1454{
fd0c2bd1 1455 FRAME_PTR f;
dc6f92b8
JB
1456 register Lisp_Object tail, elt, prop, val;
1457
ff11dfa1
JB
1458 if (EQ (frame, Qnil))
1459 f = selected_frame;
dc6f92b8
JB
1460 else
1461 {
ff11dfa1
JB
1462 CHECK_LIVE_FRAME (frame, 0);
1463 f = XFRAME (frame);
dc6f92b8
JB
1464 }
1465
dbc4e1c1 1466 /* I think this should be done with a hook. */
fd0c2bd1
JB
1467#ifdef HAVE_X_WINDOWS
1468 if (FRAME_X_P (f))
1469#if 1
1470 x_set_frame_parameters (f, alist);
1471#else
dc6f92b8
JB
1472 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1473 {
1474 elt = Fcar (tail);
1475 prop = Fcar (elt);
1476 val = Fcdr (elt);
fd0c2bd1 1477 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
ff11dfa1 1478 store_frame_param (f, prop, val);
dc6f92b8 1479 }
fd0c2bd1
JB
1480#endif
1481#endif
dc6f92b8
JB
1482
1483 return Qnil;
1484}
1485\f
a26a1f95
RS
1486DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1487 0, 1, 0,
1488 "Height in pixels of a line in the font in frame FRAME.\n\
1489If FRAME is omitted, the selected frame is used.\n\
1490For a terminal frame, the value is always 1.")
ff11dfa1
JB
1491 (frame)
1492 Lisp_Object frame;
dc6f92b8 1493{
a26a1f95 1494 struct frame *f;
dc6f92b8 1495
a26a1f95
RS
1496 if (NILP (frame))
1497 f = selected_frame;
1498 else
1499 {
1500 CHECK_FRAME (frame, 0);
1501 f = XFRAME (frame);
1502 }
1503
1504#ifdef HAVE_X_WINDOWS
1505 if (FRAME_X_P (f))
1506 return make_number (x_char_height (f));
1507 else
dc6d9681 1508#endif
a26a1f95
RS
1509 return make_number (1);
1510}
dc6d9681 1511
dc6f92b8 1512
a26a1f95
RS
1513DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1514 0, 1, 0,
1515 "Width in pixels of characters in the font in frame FRAME.\n\
1516If FRAME is omitted, the selected frame is used.\n\
1517The width is the same for all characters, because\n\
1518currently Emacs supports only fixed-width fonts.\n\
1519For a terminal screen, the value is always 1.")
1520 (frame)
1521 Lisp_Object frame;
dc6f92b8 1522{
a26a1f95
RS
1523 struct frame *f;
1524
1525 if (NILP (frame))
1526 f = selected_frame;
1527 else
1528 {
1529 CHECK_FRAME (frame, 0);
1530 f = XFRAME (frame);
1531 }
1532
1533#ifdef HAVE_X_WINDOWS
1534 if (FRAME_X_P (f))
1535 return make_number (x_char_width (f));
1536 else
1537#endif
1538 return make_number (1);
dc6f92b8
JB
1539}
1540
a26a1f95
RS
1541DEFUN ("frame-pixel-height", Fframe_pixel_height,
1542 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1543 "Return a FRAME's height in pixels.\n\
1544For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1545If FRAME is omitted, the selected frame is used.")
1546 (frame)
1547 Lisp_Object frame;
dc6f92b8 1548{
a26a1f95
RS
1549 struct frame *f;
1550
1551 if (NILP (frame))
1552 f = selected_frame;
1553 else
1554 {
1555 CHECK_FRAME (frame, 0);
1556 f = XFRAME (frame);
1557 }
1558
1559#ifdef HAVE_X_WINDOWS
1560 if (FRAME_X_P (f))
1561 return make_number (x_pixel_height (f));
1562 else
dc6d9681 1563#endif
a26a1f95
RS
1564 return make_number (FRAME_HEIGHT (f));
1565}
1566
1567DEFUN ("frame-pixel-width", Fframe_pixel_width,
1568 Sframe_pixel_width, 0, 1, 0,
1569 "Return FRAME's width in pixels.\n\
164a14ef 1570For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
1571If FRAME is omitted, the selected frame is used.")
1572 (frame)
1573 Lisp_Object frame;
1574{
1575 struct frame *f;
1576
1577 if (NILP (frame))
1578 f = selected_frame;
1579 else
1580 {
1581 CHECK_FRAME (frame, 0);
1582 f = XFRAME (frame);
1583 }
dc6f92b8 1584
a26a1f95
RS
1585#ifdef HAVE_X_WINDOWS
1586 if (FRAME_X_P (f))
1587 return make_number (x_pixel_width (f));
1588 else
1589#endif
1590 return make_number (FRAME_WIDTH (f));
1591}
1592\f
ff11dfa1
JB
1593DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1594 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1595Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1596but that the idea of the actual height of the frame should not be changed.")
1597 (frame, rows, pretend)
fd0c2bd1 1598 Lisp_Object frame, rows, pretend;
dc6f92b8 1599{
ff11dfa1 1600 register struct frame *f;
dc6f92b8
JB
1601
1602 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1603 if (NILP (frame))
1604 f = selected_frame;
dc6f92b8
JB
1605 else
1606 {
ff11dfa1
JB
1607 CHECK_LIVE_FRAME (frame, 0);
1608 f = XFRAME (frame);
dc6f92b8
JB
1609 }
1610
dbc4e1c1 1611 /* I think this should be done with a hook. */
fd0c2bd1
JB
1612#ifdef HAVE_X_WINDOWS
1613 if (FRAME_X_P (f))
dc6f92b8 1614 {
3558db6f 1615 if (XINT (rows) != f->height)
808c0f20 1616 x_set_window_size (f, 1, f->width, XINT (rows));
dc6f92b8
JB
1617 }
1618 else
fd0c2bd1
JB
1619#endif
1620 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1621 return Qnil;
1622}
1623
ff11dfa1
JB
1624DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1625 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1626Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1627but that the idea of the actual width of the frame should not be changed.")
1628 (frame, cols, pretend)
fd0c2bd1 1629 Lisp_Object frame, cols, pretend;
dc6f92b8 1630{
ff11dfa1 1631 register struct frame *f;
dc6f92b8 1632 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1633 if (NILP (frame))
1634 f = selected_frame;
dc6f92b8
JB
1635 else
1636 {
ff11dfa1
JB
1637 CHECK_LIVE_FRAME (frame, 0);
1638 f = XFRAME (frame);
dc6f92b8
JB
1639 }
1640
dbc4e1c1 1641 /* I think this should be done with a hook. */
fd0c2bd1
JB
1642#ifdef HAVE_X_WINDOWS
1643 if (FRAME_X_P (f))
dc6f92b8 1644 {
ff11dfa1 1645 if (XINT (cols) != f->width)
808c0f20 1646 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
1647 }
1648 else
fd0c2bd1
JB
1649#endif
1650 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1651 return Qnil;
1652}
1653
ff11dfa1
JB
1654DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1655 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1656 (frame, cols, rows)
1657 Lisp_Object frame, cols, rows;
dc6f92b8 1658{
ff11dfa1 1659 register struct frame *f;
dc6f92b8
JB
1660 int mask;
1661
ff11dfa1 1662 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1663 CHECK_NUMBER (cols, 2);
1664 CHECK_NUMBER (rows, 1);
ff11dfa1 1665 f = XFRAME (frame);
dc6f92b8 1666
dbc4e1c1 1667 /* I think this should be done with a hook. */
fd0c2bd1
JB
1668#ifdef HAVE_X_WINDOWS
1669 if (FRAME_X_P (f))
dc6f92b8 1670 {
ff11dfa1 1671 if (XINT (rows) != f->height || XINT (cols) != f->width)
808c0f20 1672 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
1673 }
1674 else
fd0c2bd1
JB
1675#endif
1676 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1677
1678 return Qnil;
1679}
1680
ff11dfa1
JB
1681DEFUN ("set-frame-position", Fset_frame_position,
1682 Sset_frame_position, 3, 3, 0,
1683 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
1684This is actually the position of the upper left corner of the frame.\n\
1685Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 1686the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
1687 (frame, xoffset, yoffset)
1688 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1689{
ff11dfa1 1690 register struct frame *f;
dc6f92b8
JB
1691 int mask;
1692
ff11dfa1 1693 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1694 CHECK_NUMBER (xoffset, 1);
1695 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1696 f = XFRAME (frame);
dc6f92b8 1697
dbc4e1c1 1698 /* I think this should be done with a hook. */
fd0c2bd1
JB
1699#ifdef HAVE_X_WINDOWS
1700 if (FRAME_X_P (f))
c7c70761 1701 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 1702#endif
dc6f92b8
JB
1703
1704 return Qt;
1705}
dc6d9681 1706
dc6f92b8 1707\f
ff11dfa1 1708choose_minibuf_frame ()
dc6f92b8 1709{
ff11dfa1
JB
1710 /* For lowest-level minibuf, put it on currently selected frame
1711 if frame has a minibuffer. */
d06a8a56 1712
dc6f92b8 1713 if (minibuf_level == 0
ff11dfa1 1714 && selected_frame != 0
d06a8a56 1715 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1716 {
d06a8a56
JB
1717 /* I don't think that any frames may validly have a null minibuffer
1718 window anymore. */
1719 if (NILP (selected_frame->minibuffer_window))
1720 abort ();
1721
ff11dfa1 1722 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1723 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1724 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1725 }
1726}
1727\f
ff11dfa1 1728syms_of_frame ()
dc6f92b8 1729{
fd0c2bd1 1730 /*&&& init symbols here &&&*/
ff11dfa1 1731 Qframep = intern ("framep");
ff11dfa1 1732 staticpro (&Qframep);
dbc4e1c1
JB
1733 Qframe_live_p = intern ("frame-live-p");
1734 staticpro (&Qframe_live_p);
fd0c2bd1
JB
1735 Qheight = intern ("height");
1736 staticpro (&Qheight);
1737 Qicon = intern ("icon");
1738 staticpro (&Qicon);
1739 Qminibuffer = intern ("minibuffer");
bc93c097 1740 staticpro (&Qminibuffer);
fd0c2bd1
JB
1741 Qmodeline = intern ("modeline");
1742 staticpro (&Qmodeline);
1743 Qname = intern ("name");
1744 staticpro (&Qname);
fd0c2bd1
JB
1745 Qonly = intern ("only");
1746 staticpro (&Qonly);
1747 Qunsplittable = intern ("unsplittable");
1748 staticpro (&Qunsplittable);
f7af3f7b
RS
1749 Qmenu_bar_lines = intern ("menu-bar-lines");
1750 staticpro (&Qmenu_bar_lines);
fd0c2bd1
JB
1751 Qwidth = intern ("width");
1752 staticpro (&Qwidth);
1753 Qx = intern ("x");
1754 staticpro (&Qx);
f7af3f7b
RS
1755 Qvisible = intern ("visible");
1756 staticpro (&Qvisible);
dc6f92b8 1757
ff11dfa1 1758 staticpro (&Vframe_list);
dc6f92b8 1759
ff11dfa1
JB
1760 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1761 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1762
1763 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1764 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1765 Vemacs_iconified = Qnil;
1766
ff11dfa1
JB
1767 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1768 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1769\n\
ff11dfa1 1770Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1771appropriate surrogate.\n\
1772\n\
1773Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1774frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1775minibuffer, no matter what this variable is set to. This means that\n\
1776this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1777current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1778displayed.");
ff11dfa1 1779 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1780
ff11dfa1
JB
1781 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1782 "Alist of default values for frame creation.\n\
5bce042c 1783These may be set in your init file, like this:\n\
1855c8dd
RS
1784 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
1785These override values given in window system configuration data,\n\
1786 including X Windows' defaults database.\n\
ff11dfa1
JB
1787For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1788For values specific to the separate minibuffer frame, see\n\
1855c8dd
RS
1789 `minibuffer-frame-alist'.\n\
1790The `menu-bar-lines' element of the list controls whether new frames\n\
169e69a3 1791 have menu bars; `menu-bar-mode' works by altering this element.");
ff11dfa1
JB
1792 Vdefault_frame_alist = Qnil;
1793
1794 defsubr (&Sframep);
dbc4e1c1 1795 defsubr (&Sframe_live_p);
0f85737c 1796 defsubr (&Shandle_switch_frame);
ff11dfa1
JB
1797 defsubr (&Sselect_frame);
1798 defsubr (&Sselected_frame);
1799 defsubr (&Swindow_frame);
1800 defsubr (&Sframe_root_window);
d446a856 1801 defsubr (&Sframe_first_window);
ff11dfa1 1802 defsubr (&Sframe_selected_window);
4a7cfafc 1803 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
1804 defsubr (&Sframe_list);
1805 defsubr (&Snext_frame);
ef2c57ac 1806 defsubr (&Sprevious_frame);
ff11dfa1 1807 defsubr (&Sdelete_frame);
f9898cc6 1808 defsubr (&Smouse_position);
152e6c70 1809 defsubr (&Smouse_pixel_position);
dc6f92b8 1810 defsubr (&Sset_mouse_position);
152e6c70 1811 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 1812#if 0
ff11dfa1
JB
1813 defsubr (&Sframe_configuration);
1814 defsubr (&Srestore_frame_configuration);
dc6f92b8 1815#endif
ff11dfa1
JB
1816 defsubr (&Smake_frame_visible);
1817 defsubr (&Smake_frame_invisible);
1818 defsubr (&Siconify_frame);
1819 defsubr (&Sframe_visible_p);
1820 defsubr (&Svisible_frame_list);
b49f5578
JB
1821 defsubr (&Sraise_frame);
1822 defsubr (&Slower_frame);
ff11dfa1
JB
1823 defsubr (&Sredirect_frame_focus);
1824 defsubr (&Sframe_focus);
1825 defsubr (&Sframe_parameters);
1826 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
1827 defsubr (&Sframe_char_height);
1828 defsubr (&Sframe_char_width);
1829 defsubr (&Sframe_pixel_height);
1830 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
1831 defsubr (&Sset_frame_height);
1832 defsubr (&Sset_frame_width);
1833 defsubr (&Sset_frame_size);
1834 defsubr (&Sset_frame_position);
dc6f92b8 1835}
e5d77022 1836
2f0b07e0
JB
1837keys_of_frame ()
1838{
0f85737c 1839 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 1840 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
8af6db06
KH
1841 initial_define_lispy_key (global_map, "iconify-frame", "ignore");
1842 initial_define_lispy_key (global_map, "make-frame-visible", "ignore");
2f0b07e0 1843}
a26a1f95 1844\f
d06a8a56 1845#else /* not MULTI_FRAME */
fd0c2bd1 1846
cc38027b
JB
1847/* If we're not using multi-frame stuff, we still need to provide some
1848 support functions. */
1849
f769f1b2
KH
1850Lisp_Object Qheight;
1851Lisp_Object Qminibuffer;
1852Lisp_Object Qmodeline;
1853Lisp_Object Qname;
1854Lisp_Object Qunsplittable;
1855Lisp_Object Qmenu_bar_lines;
1856Lisp_Object Qwidth;
1857
91f5a8d7
KH
1858Lisp_Object Vterminal_frame;
1859
cc38027b
JB
1860/* Unless this function is defined, providing set-frame-height and
1861 set-frame-width doesn't help compatibility any, since they both
1862 want this as their first argument. */
1863DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
9597f4b8
KH
1864 /* Don't confuse make-docfile by having two doc strings for this function.
1865 make-docfile does not pay attention to #if, for good reason! */
1866 0)
cc38027b
JB
1867 ()
1868{
87485d6f
MW
1869 /* For your possible information, this code is unfolded into the
1870 second WINDOW_FRAME in frame.h. */
cc38027b 1871 Lisp_Object tem;
f4e93c40 1872 XSETFASTINT (tem, 0);
cc38027b
JB
1873 return tem;
1874}
888f3d05
RS
1875
1876DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
1877 0)
1878 (frame)
1879 Lisp_Object frame;
1880{
1881 Lisp_Object w;
1882
1883 w = FRAME_ROOT_WINDOW (selected_frame);
1884
1885 while (NILP (XWINDOW (w)->buffer))
1886 {
1887 if (! NILP (XWINDOW (w)->hchild))
1888 w = XWINDOW (w)->hchild;
1889 else if (! NILP (XWINDOW (w)->vchild))
1890 w = XWINDOW (w)->vchild;
1891 else
1892 abort ();
1893 }
1894 return w;
1895}
1896
704a9b45 1897DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
9597f4b8
KH
1898 /* Don't confuse make-docfile by having two doc strings for this function.
1899 make-docfile does not pay attention to #if, for good reason! */
1900 0)
704a9b45
RS
1901 (object)
1902 Lisp_Object object;
1903{
87485d6f
MW
1904#ifdef MSDOS
1905 if (FRAME_X_P (object))
1906 return intern ("pc");
1907#endif
704a9b45
RS
1908 return Qnil;
1909}
fd0c2bd1
JB
1910
1911DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
9597f4b8
KH
1912 /* Don't confuse make-docfile by having two doc strings for this function.
1913 make-docfile does not pay attention to #if, for good reason! */
1914 0)
fd0c2bd1
JB
1915 (frame, rows, pretend)
1916 Lisp_Object frame, rows, pretend;
1917{
1918 CHECK_NUMBER (rows, 0);
1919
1920 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1921 return Qnil;
1922}
1923
1924DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
9597f4b8
KH
1925 /* Don't confuse make-docfile by having two doc strings for this function.
1926 make-docfile does not pay attention to #if, for good reason! */
1927 0)
fd0c2bd1
JB
1928 (frame, cols, pretend)
1929 Lisp_Object frame, cols, pretend;
1930{
1931 CHECK_NUMBER (cols, 0);
1932
1933 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1934 return Qnil;
1935}
1936
1937DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
9597f4b8
KH
1938 /* Don't confuse make-docfile by having two doc strings for this function.
1939 make-docfile does not pay attention to #if, for good reason! */
1940 0)
fd0c2bd1
JB
1941 (frame, cols, rows)
1942 Lisp_Object frame, cols, rows;
1943{
1944 CHECK_NUMBER (cols, 2);
1945 CHECK_NUMBER (rows, 1);
1946
1947 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1948
1949 return Qnil;
1950}
b6d8a44f 1951\f
48c9d487
JB
1952DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1953 "Return number of lines available for display on FRAME.\n\
1954If FRAME is omitted, describe the currently selected frame.")
1955 (frame)
1956 Lisp_Object frame;
cc38027b
JB
1957{
1958 return make_number (FRAME_HEIGHT (selected_frame));
1959}
1960
48c9d487
JB
1961DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1962 "Return number of columns available for display on FRAME.\n\
1963If FRAME is omitted, describe the currently selected frame.")
1964 (frame)
1965 Lisp_Object frame;
cc38027b
JB
1966{
1967 return make_number (FRAME_WIDTH (selected_frame));
1968}
1969
a26a1f95
RS
1970DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1971 0, 1, 0,
9597f4b8
KH
1972 /* Don't confuse make-docfile by having two doc strings for this function.
1973 make-docfile does not pay attention to #if, for good reason! */
1974 0)
a26a1f95
RS
1975 (frame)
1976 Lisp_Object frame;
1977{
1978 return make_number (1);
1979}
1980
1981
1982DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1983 0, 1, 0,
9597f4b8
KH
1984 /* Don't confuse make-docfile by having two doc strings for this function.
1985 make-docfile does not pay attention to #if, for good reason! */
1986 0)
a26a1f95
RS
1987 (frame)
1988 Lisp_Object frame;
1989{
1990 return make_number (1);
1991}
1992
1993DEFUN ("frame-pixel-height", Fframe_pixel_height,
1994 Sframe_pixel_height, 0, 1, 0,
9597f4b8
KH
1995 /* Don't confuse make-docfile by having two doc strings for this function.
1996 make-docfile does not pay attention to #if, for good reason! */
1997 0)
a26a1f95
RS
1998 (frame)
1999 Lisp_Object frame;
2000{
2001 return make_number (FRAME_HEIGHT (f));
2002}
2003
2004DEFUN ("frame-pixel-width", Fframe_pixel_width,
2005 Sframe_pixel_width, 0, 1, 0,
9597f4b8
KH
2006 /* Don't confuse make-docfile by having two doc strings for this function.
2007 make-docfile does not pay attention to #if, for good reason! */
2008 0)
a26a1f95
RS
2009 (frame)
2010 Lisp_Object frame;
2011{
2012 return make_number (FRAME_WIDTH (f));
2013}
2014
cc38027b
JB
2015/* These are for backward compatibility with Emacs 18. */
2016
fd0c2bd1
JB
2017DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
2018 "Tell redisplay that the screen has LINES lines.\n\
2019Optional second arg non-nil means that redisplay should use LINES lines\n\
2020but that the idea of the actual height of the screen should not be changed.")
2021 (lines, pretend)
2022 Lisp_Object lines, pretend;
2023{
2024 CHECK_NUMBER (lines, 0);
2025
2026 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
2027 return Qnil;
2028}
2029
2030DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
2031 "Tell redisplay that the screen has COLS columns.\n\
2032Optional second arg non-nil means that redisplay should use COLS columns\n\
2033but that the idea of the actual width of the screen should not be changed.")
2034 (cols, pretend)
2035 Lisp_Object cols, pretend;
2036{
2037 CHECK_NUMBER (cols, 0);
2038
2039 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2040 return Qnil;
2041}
2042
bc1ed486 2043DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
76db7eb4
KH
2044 /* Don't confuse make-docfile by having two doc strings for this function.
2045 make-docfile does not pay attention to #if, for good reason! */
2046 0)
bc1ed486
RS
2047 ()
2048{
87485d6f
MW
2049#ifdef HAVE_MOUSE
2050 if (mouse_position_hook)
2051 {
2052 FRAME_PTR f;
2053 Lisp_Object lispy_dummy;
2054 enum scroll_bar_part party_dummy;
2055 Lisp_Object x, y;
2056 unsigned long long_dummy;
2057
2058 (*mouse_position_hook) (&f,
2059 &lispy_dummy, &party_dummy,
2060 &x, &y,
2061 &long_dummy);
2062 return Fcons (Fselected_frame (), Fcons (x, y));
2063 }
2064#endif
76db7eb4 2065 return Fcons (Qnil, Fcons (Qnil, Qnil));
bc1ed486 2066}
b6d8a44f 2067\f
f769f1b2
KH
2068void
2069store_in_alist (alistptr, prop, val)
2070 Lisp_Object *alistptr, val;
2071 Lisp_Object prop;
2072{
2073 register Lisp_Object tem;
2074
2075 tem = Fassq (prop, *alistptr);
2076 if (EQ (tem, Qnil))
2077 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2078 else
2079 Fsetcdr (tem, val);
2080}
2081
b6d8a44f 2082DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
42652599
KH
2083 /* Don't confuse make-docfile by having two doc strings for this function.
2084 make-docfile does not pay attention to #if, for good reason! */
2085 0)
b6d8a44f
RS
2086 (frame)
2087 Lisp_Object frame;
2088{
f769f1b2
KH
2089 Lisp_Object alist;
2090 FRAME_PTR f;
2091
2092 if (EQ (frame, Qnil))
2093 f = selected_frame;
2094 else
2095 {
2096 CHECK_FRAME (frame, 0);
2097 f = XFRAME (frame);
2098 }
2099
2100 if (!FRAME_LIVE_P (f))
2101 return Qnil;
2102
2103 alist = Qnil;
87485d6f
MW
2104#ifdef MSDOS
2105 if (FRAME_X_P (f))
2106 {
2107 static char *colornames[16] =
2108 {
2109 "black", "blue", "green", "cyan", "red", "magenta", "brown",
2110 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
2111 "lightred", "lightmagenta", "yellow", "white"
2112 };
2113 store_in_alist (&alist, intern ("foreground-color"),
2114 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
2115 store_in_alist (&alist, intern ("background-color"),
2116 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
2117 }
2118#endif
2119 store_in_alist (&alist, intern ("font"), build_string ("default"));
f769f1b2
KH
2120 store_in_alist (&alist, Qname, build_string ("emacs"));
2121 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
2122 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
2123 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2124 store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
2125 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2126 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
2127
2128 return alist;
b6d8a44f
RS
2129}
2130
2131DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2132 Smodify_frame_parameters, 2, 2, 0,
42652599
KH
2133 /* Don't confuse make-docfile by having two doc strings for this function.
2134 make-docfile does not pay attention to #if, for good reason! */
2135 0)
b6d8a44f
RS
2136 (frame, alist)
2137 Lisp_Object frame, alist;
2138{
87485d6f
MW
2139#ifdef MSDOS
2140 if (FRAME_X_P (frame))
2141 IT_set_frame_parameters (XFRAME (frame), alist);
2142#endif
b6d8a44f
RS
2143 return Qnil;
2144}
bc1ed486 2145
52ed2dad
RS
2146DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
2147 /* Don't confuse make-docfile by having two doc strings for this function.
2148 make-docfile does not pay attention to #if, for good reason! */
2149 0)
2150 (frame)
2151 Lisp_Object frame;
2152{
2153 return Qt;
2154}
2155
87485d6f
MW
2156DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
2157 /* Don't confuse make-docfile by having two doc strings for this function.
2158 make-docfile does not pay attention to #if, for good reason! */
2159 0)
2160 ()
2161{
2162 return Fcons (Fselected_frame (), Qnil);
2163}
2164
fd0c2bd1
JB
2165syms_of_frame ()
2166{
f769f1b2
KH
2167 Qheight = intern ("height");
2168 staticpro (&Qheight);
2169 Qminibuffer = intern ("minibuffer");
2170 staticpro (&Qminibuffer);
2171 Qmodeline = intern ("modeline");
2172 staticpro (&Qmodeline);
2173 Qname = intern ("name");
2174 staticpro (&Qname);
2175 Qunsplittable = intern ("unsplittable");
2176 staticpro (&Qunsplittable);
2177 Qmenu_bar_lines = intern ("menu-bar-lines");
2178 staticpro (&Qmenu_bar_lines);
2179 Qwidth = intern ("width");
2180 staticpro (&Qwidth);
2181
91f5a8d7
KH
2182 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2183 "The initial frame-object, which represents Emacs's stdout.");
f4e93c40 2184 XSETFASTINT (Vterminal_frame, 0);
91f5a8d7 2185
a26a1f95 2186 defsubr (&Sselected_frame);
888f3d05 2187 defsubr (&Sframe_first_window);
704a9b45 2188 defsubr (&Sframep);
a26a1f95
RS
2189 defsubr (&Sframe_char_height);
2190 defsubr (&Sframe_char_width);
2191 defsubr (&Sframe_pixel_height);
2192 defsubr (&Sframe_pixel_width);
fd0c2bd1
JB
2193 defsubr (&Sset_frame_height);
2194 defsubr (&Sset_frame_width);
2195 defsubr (&Sset_frame_size);
2196 defsubr (&Sset_screen_height);
2197 defsubr (&Sset_screen_width);
2198 defsubr (&Sframe_height);
2199 Ffset (intern ("screen-height"), intern ("frame-height"));
2200 defsubr (&Sframe_width);
2201 Ffset (intern ("screen-width"), intern ("frame-width"));
bc1ed486 2202 defsubr (&Smouse_position);
b6d8a44f
RS
2203 defsubr (&Sframe_parameters);
2204 defsubr (&Smodify_frame_parameters);
52ed2dad 2205 defsubr (&Sframe_live_p);
87485d6f
MW
2206 defsubr (&Sframe_list);
2207
2208#ifdef MSDOS
2209 /* A comment in dispnew.c says the_only_frame is not protected. */
2210 the_only_frame.face_alist = Qnil;
2211 staticpro (&the_only_frame.face_alist);
2212 the_only_frame.menu_bar_items = Qnil;
2213 staticpro (&the_only_frame.menu_bar_items);
2214 the_only_frame.menu_bar_vector = Qnil;
2215 staticpro (&the_only_frame.menu_bar_vector);
2216 the_only_frame.menu_bar_items = menu_bar_items (Qnil);
2217#endif
fd0c2bd1
JB
2218}
2219
2f0b07e0
JB
2220keys_of_frame ()
2221{
2222}
2223
fd0c2bd1 2224#endif /* not MULTI_FRAME */