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