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