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