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