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