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