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