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