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