1 /* Generic frame functions.
2 Copyright (C) 1989, 1992, 1993 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
30 #include "termhooks.h"
32 /* These help us bind and responding to switch-frame events. */
36 Lisp_Object Vemacs_iconified
;
37 Lisp_Object Vframe_list
;
38 Lisp_Object Vterminal_frame
;
39 Lisp_Object Vdefault_minibuffer_frame
;
40 Lisp_Object Vdefault_frame_alist
;
42 /* Evaluate this expression to rebuild the section of syms_of_frame
43 that initializes and staticpros the symbols declared below. Note
44 that Emacs 18 has a bug that keeps C-x C-e from being able to
45 evaluate this expression.
48 ;; Accumulate a list of the symbols we want to initialize from the
49 ;; declarations at the top of the file.
50 (goto-char (point-min))
51 (search-forward "/\*&&& symbols declared here &&&*\/\n")
53 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
55 (cons (buffer-substring (match-beginning 1) (match-end 1))
58 (setq symbol-list (nreverse symbol-list))
59 ;; Delete the section of syms_of_... where we initialize the symbols.
60 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
61 (let ((start (point)))
62 (while (looking-at "^ Q")
64 (kill-region start (point)))
65 ;; Write a new symbol initialization section.
67 (insert (format " %s = intern (\"" (car symbol-list)))
68 (let ((start (point)))
69 (insert (substring (car symbol-list) 1))
70 (subst-char-in-region start (point) ?_ ?-))
71 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
72 (setq symbol-list (cdr symbol-list)))))
75 /*&&& symbols declared here &&&*/
77 Lisp_Object Qframe_live_p
;
80 Lisp_Object Qminibuffer
;
81 Lisp_Object Qmodeline
;
84 Lisp_Object Qunsplittable
;
88 extern Lisp_Object Vminibuffer_list
;
89 extern Lisp_Object
get_minibuffer ();
91 extern Lisp_Object Vlast_event_frame
;
93 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
94 "Return non-nil if OBJECT is a frame.\n\
95 Value is t for a termcap frame (a character-only terminal),\n\
96 `x' for an Emacs frame that is really an X window.\n\
97 Also see `live-frame-p'.")
101 if (XTYPE (object
) != Lisp_Frame
)
103 switch (XFRAME (object
)->output_method
)
107 case output_x_window
:
114 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
115 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
116 Value is nil if OBJECT is not a live frame. If object is a live\n\
117 frame, the return value indicates what sort of output device it is\n\
118 displayed on. Value is t for a termcap frame (a character-only\n\
119 terminal), `x' for an Emacs frame being displayed in an X window.")
123 return ((FRAMEP (object
)
124 && FRAME_LIVE_P (XFRAME (object
)))
134 register struct frame
*f
;
135 register Lisp_Object root_window
;
136 register Lisp_Object mini_window
;
138 frame
= Fmake_vector (((sizeof (struct frame
) - (sizeof (Lisp_Vector
)
139 - sizeof (Lisp_Object
)))
140 / sizeof (Lisp_Object
)),
142 XSETTYPE (frame
, Lisp_Frame
);
147 f
->current_glyphs
= 0;
148 f
->desired_glyphs
= 0;
150 f
->async_visible
= 0;
151 f
->display
.nothing
= 0;
153 f
->async_iconified
= 0;
154 f
->wants_modeline
= 1;
159 f
->has_minibuffer
= mini_p
;
160 f
->focus_frame
= Qnil
;
161 f
->explicit_name
= 0;
162 f
->can_have_scrollbars
= 0;
163 f
->has_vertical_scrollbars
= 0;
164 f
->param_alist
= Qnil
;
165 f
->scrollbars
= Qnil
;
166 f
->condemned_scrollbars
= Qnil
;
168 root_window
= make_window ();
171 mini_window
= make_window ();
172 XWINDOW (root_window
)->next
= mini_window
;
173 XWINDOW (mini_window
)->prev
= root_window
;
174 XWINDOW (mini_window
)->mini_p
= Qt
;
175 XWINDOW (mini_window
)->frame
= frame
;
176 f
->minibuffer_window
= mini_window
;
181 XWINDOW (root_window
)->next
= Qnil
;
182 f
->minibuffer_window
= Qnil
;
185 XWINDOW (root_window
)->frame
= frame
;
188 just so that there is "something there."
189 Correct size will be set up later with change_frame_size. */
194 XFASTINT (XWINDOW (root_window
)->width
) = 10;
195 XFASTINT (XWINDOW (root_window
)->height
) = (mini_p
? 9 : 10);
199 XFASTINT (XWINDOW (mini_window
)->width
) = 10;
200 XFASTINT (XWINDOW (mini_window
)->top
) = 9;
201 XFASTINT (XWINDOW (mini_window
)->height
) = 1;
204 /* Choose a buffer for the frame's root window. */
208 XWINDOW (root_window
)->buffer
= Qt
;
209 buf
= Fcurrent_buffer ();
210 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
211 a space), try to find another one. */
212 if (XSTRING (Fbuffer_name (buf
))->data
[0] == ' ')
213 buf
= Fother_buffer (buf
, Qnil
);
214 Fset_window_buffer (root_window
, buf
);
219 XWINDOW (mini_window
)->buffer
= Qt
;
220 Fset_window_buffer (mini_window
,
221 (NILP (Vminibuffer_list
)
223 : Fcar (Vminibuffer_list
)));
226 f
->root_window
= root_window
;
227 f
->selected_window
= root_window
;
228 /* Make sure this window seems more recently used than
229 a newly-created, never-selected window. */
230 XFASTINT (XWINDOW (f
->selected_window
)->use_time
) = ++window_select_count
;
232 Vframe_list
= Fcons (frame
, Vframe_list
);
237 /* Make a frame using a separate minibuffer window on another frame.
238 MINI_WINDOW is the minibuffer window to use. nil means use the
239 default (the global minibuffer). */
242 make_frame_without_minibuffer (mini_window
)
243 register Lisp_Object mini_window
;
245 register struct frame
*f
;
247 /* Choose the minibuffer window to use. */
248 if (NILP (mini_window
))
250 if (XTYPE (Vdefault_minibuffer_frame
) != Lisp_Frame
)
251 error ("default-minibuffer-frame must be set when creating minibufferless frames");
252 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame
)))
253 error ("default-minibuffer-frame must be a live frame");
254 mini_window
= XFRAME (Vdefault_minibuffer_frame
)->minibuffer_window
;
258 CHECK_LIVE_WINDOW (mini_window
, 0);
261 /* Make a frame containing just a root window. */
264 /* Install the chosen minibuffer window, with proper buffer. */
265 f
->minibuffer_window
= mini_window
;
266 Fset_window_buffer (mini_window
,
267 (NILP (Vminibuffer_list
)
269 : Fcar (Vminibuffer_list
)));
273 /* Make a frame containing only a minibuffer window. */
276 make_minibuffer_frame ()
278 /* First make a frame containing just a root window, no minibuffer. */
280 register struct frame
*f
= make_frame (0);
281 register Lisp_Object mini_window
;
282 register Lisp_Object frame
;
284 XSET (frame
, Lisp_Frame
, f
);
289 f
->wants_modeline
= 0;
290 f
->has_minibuffer
= 1;
292 /* Now label the root window as also being the minibuffer.
293 Avoid infinite looping on the window chain by marking next pointer
296 mini_window
= f
->minibuffer_window
= f
->root_window
;
297 XWINDOW (mini_window
)->mini_p
= Qt
;
298 XWINDOW (mini_window
)->next
= Qnil
;
299 XWINDOW (mini_window
)->prev
= Qnil
;
300 XWINDOW (mini_window
)->frame
= frame
;
302 /* Put the proper buffer in that window. */
304 Fset_window_buffer (mini_window
,
305 (NILP (Vminibuffer_list
)
307 : Fcar (Vminibuffer_list
)));
311 /* Construct a frame that refers to the terminal (stdin and stdout). */
314 make_terminal_frame ()
316 register struct frame
*f
;
320 f
->name
= build_string ("terminal");
321 FRAME_SET_VISIBLE (f
, 1);
322 f
->display
.nothing
= 1; /* Nonzero means frame isn't deleted. */
323 XSET (Vterminal_frame
, Lisp_Frame
, f
);
327 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
328 "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
329 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
330 focus on that frame.\n\
332 This function is interactive, and may be bound to the ``switch-frame''\n\
333 event; when invoked this way, it switches to the frame named in the\n\
334 event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
335 if it is, select the frame named in the event.\n\
337 Changing the selected frame can change focus redirections. See\n\
338 `redirect-frame-focus' for details.")
340 Lisp_Object frame
, no_enter
;
342 /* If FRAME is a switch-frame event, extract the frame we should
345 && EQ (XCONS (frame
)->car
, Qswitch_frame
)
346 && CONSP (XCONS (frame
)->cdr
))
347 frame
= XCONS (XCONS (frame
)->cdr
)->car
;
349 CHECK_LIVE_FRAME (frame
, 0);
351 if (selected_frame
== XFRAME (frame
))
354 /* If a frame's focus has been redirected toward the currently
355 selected frame, we should change the redirection to point to the
356 newly selected frame. This means that if the focus is redirected
357 from a minibufferless frame to a surrogate minibuffer frame, we
358 can use `other-window' to switch between all the frames using
359 that minibuffer frame, and the focus redirection will follow us
364 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
368 if (XTYPE (XCONS (tail
)->car
) != Lisp_Frame
)
371 focus
= FRAME_FOCUS_FRAME (XFRAME (XCONS (tail
)->car
));
373 if (XTYPE (focus
) == Lisp_Frame
374 && XFRAME (focus
) == selected_frame
)
375 Fredirect_frame_focus (XCONS (tail
)->car
, frame
);
379 selected_frame
= XFRAME (frame
);
380 if (! FRAME_MINIBUF_ONLY_P (selected_frame
))
381 last_nonminibuf_frame
= selected_frame
;
383 Fselect_window (XFRAME (frame
)->selected_window
);
385 /* I think this should be done with a hook. */
386 #ifdef HAVE_X_WINDOWS
387 if (FRAME_X_P (XFRAME (frame
))
390 Ffocus_frame (frame
);
393 choose_minibuf_frame ();
395 /* We want to make sure that the next event generates a frame-switch
396 event to the appropriate frame. This seems kludgey to me, but
397 before you take it out, make sure that evaluating something like
398 (select-window (frame-root-window (new-frame))) doesn't end up
399 with your typing being interpreted in the new frame instead of
400 the one you're actually typing in. */
401 Vlast_event_frame
= Qnil
;
406 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
407 "Return the frame that is now selected.")
411 XSET (tem
, Lisp_Frame
, selected_frame
);
415 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 1, 1, 0,
416 "Return the frame object that window WINDOW is on.")
420 CHECK_LIVE_WINDOW (window
, 0);
421 return XWINDOW (window
)->frame
;
424 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
425 "Returns the root-window of FRAME.\n\
426 If omitted, FRAME defaults to the currently selected frame.")
431 XSET (frame
, Lisp_Frame
, selected_frame
);
433 CHECK_LIVE_FRAME (frame
, 0);
435 return XFRAME (frame
)->root_window
;
438 DEFUN ("frame-selected-window", Fframe_selected_window
,
439 Sframe_selected_window
, 0, 1, 0,
440 "Return the selected window of frame object FRAME.\n\
441 If omitted, FRAME defaults to the currently selected frame.")
446 XSET (frame
, Lisp_Frame
, selected_frame
);
448 CHECK_LIVE_FRAME (frame
, 0);
450 return XFRAME (frame
)->selected_window
;
453 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
455 "Return a list of all frames.")
458 return Fcopy_sequence (Vframe_list
);
461 /* Return the next frame in the frame list after FRAME.
462 If MINIBUF is nil, exclude minibuffer-only frames.
463 If MINIBUF is a window, include only frames using that window for
465 If MINIBUF is non-nil, and not a window, include all frames. */
467 next_frame (frame
, minibuf
)
474 /* There must always be at least one frame in Vframe_list. */
475 if (! CONSP (Vframe_list
))
478 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
479 forever. Forestall that. */
480 CHECK_LIVE_FRAME (frame
, 0);
483 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
485 Lisp_Object f
= XCONS (tail
)->car
;
489 /* Decide whether this frame is eligible to be returned. */
491 /* If we've looped all the way around without finding any
492 eligible frames, return the original frame. */
496 /* Let minibuf decide if this frame is acceptable. */
499 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
502 else if (XTYPE (minibuf
) == Lisp_Window
)
504 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
))
516 /* Return the previous frame in the frame list before FRAME.
517 If MINIBUF is nil, exclude minibuffer-only frames.
518 If MINIBUF is a window, include only frames using that window for
520 If MINIBUF is non-nil and not a window, include all frames. */
522 prev_frame (frame
, minibuf
)
529 /* There must always be at least one frame in Vframe_list. */
530 if (! CONSP (Vframe_list
))
534 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
536 Lisp_Object f
= XCONS (tail
)->car
;
538 if (XTYPE (f
) != Lisp_Frame
)
541 if (EQ (frame
, f
) && !NILP (prev
))
544 /* Decide whether this frame is eligible to be returned,
545 according to minibuf. */
548 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
551 else if (XTYPE (minibuf
) == Lisp_Window
)
553 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
))
560 /* We've scanned the entire list. */
562 /* We went through the whole frame list without finding a single
563 acceptable frame. Return the original frame. */
566 /* There were no acceptable frames in the list before FRAME; otherwise,
567 we would have returned directly from the loop. Since PREV is the last
568 acceptable frame in the list, return it. */
572 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
573 "Return the next frame in the frame list after FRAME.\n\
574 By default, skip minibuffer-only frames.\n\
575 If omitted, FRAME defaults to the selected frame.\n\
576 If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
577 If MINIFRAME is a window, include only frames using that window for their\n\
579 If MINIFRAME is non-nil and not a window, include all frames.")
581 Lisp_Object frame
, miniframe
;
586 XSET (frame
, Lisp_Frame
, selected_frame
);
588 CHECK_LIVE_FRAME (frame
, 0);
590 return next_frame (frame
, miniframe
);
594 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 1, "",
595 "Delete FRAME, permanently eliminating it from use.\n\
596 If omitted, FRAME defaults to the selected frame.\n\
597 A frame may not be deleted if its minibuffer is used by other frames.")
603 if (EQ (frame
, Qnil
))
606 XSET (frame
, Lisp_Frame
, f
);
610 CHECK_FRAME (frame
, 0);
614 if (! FRAME_LIVE_P (f
))
617 /* Are there any other frames besides this one? */
618 if (f
== selected_frame
&& EQ (next_frame (frame
, Qt
), frame
))
619 error ("Attempt to delete the only frame");
621 /* Does this frame have a minibuffer, and is it the surrogate
622 minibuffer for any other frame? */
623 if (FRAME_HAS_MINIBUF_P (XFRAME (frame
)))
627 for (frames
= Vframe_list
;
629 frames
= XCONS (frames
)->cdr
)
631 Lisp_Object
this = XCONS (frames
)->car
;
633 if (! EQ (this, frame
)
637 (FRAME_MINIBUF_WINDOW
639 error ("Attempt to delete a surrogate minibuffer frame");
643 /* Don't let the frame remain selected. */
644 if (f
== selected_frame
)
645 Fselect_frame (next_frame (frame
, Qt
), Qnil
);
647 /* Don't allow minibuf_window to remain on a deleted frame. */
648 if (EQ (f
->minibuffer_window
, minibuf_window
))
650 Fset_window_buffer (selected_frame
->minibuffer_window
,
651 XWINDOW (minibuf_window
)->buffer
);
652 minibuf_window
= selected_frame
->minibuffer_window
;
655 /* Mark all the windows that used to be on FRAME as deleted, and then
656 remove the reference to them. */
657 delete_all_subwindows (XWINDOW (f
->root_window
));
658 f
->root_window
= Qnil
;
660 Vframe_list
= Fdelq (frame
, Vframe_list
);
661 FRAME_SET_VISIBLE (f
, 0);
663 /* Since some events are handled at the interrupt level, we may get
664 an event for f at any time; if we zero out the frame's display
665 now, then we may trip up the event-handling code. Instead, we'll
666 promise that the display of the frame must be valid until we have
667 called the window-system-dependent frame destruction routine. */
669 /* I think this should be done with a hook. */
670 #ifdef HAVE_X_WINDOWS
672 x_destroy_window (f
);
675 f
->display
.nothing
= 0;
677 /* If we've deleted the last_nonminibuf_frame, then try to find
679 if (f
== last_nonminibuf_frame
)
683 last_nonminibuf_frame
= 0;
685 for (frames
= Vframe_list
;
687 frames
= XCONS (frames
)->cdr
)
689 f
= XFRAME (XCONS (frames
)->car
);
690 if (!FRAME_MINIBUF_ONLY_P (f
))
692 last_nonminibuf_frame
= f
;
698 /* If we've deleted Vdefault_minibuffer_frame, try to find another
699 one. Prefer minibuffer-only frames, but also notice frames
700 with other windows. */
701 if (EQ (frame
, Vdefault_minibuffer_frame
))
705 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
706 Lisp_Object frame_with_minibuf
= Qnil
;
708 for (frames
= Vframe_list
;
710 frames
= XCONS (frames
)->cdr
)
712 Lisp_Object
this = XCONS (frames
)->car
;
714 if (XTYPE (this) != Lisp_Frame
)
718 if (FRAME_HAS_MINIBUF_P (f
))
720 frame_with_minibuf
= this;
721 if (FRAME_MINIBUF_ONLY_P (f
))
726 /* We know that there must be some frame with a minibuffer out
727 there. If this were not true, all of the frames present
728 would have to be minibufferless, which implies that at some
729 point their minibuffer frames must have been deleted, but
730 that is prohibited at the top; you can't delete surrogate
731 minibuffer frames. */
732 if (NILP (frame_with_minibuf
))
735 Vdefault_minibuffer_frame
= frame_with_minibuf
;
741 /* Return mouse position in character cell units. */
743 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
744 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
745 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
746 to read the mouse position, it returns the selected frame for FRAME\n\
747 and nil for X and Y.")
751 Lisp_Object lispy_dummy
;
752 enum scrollbar_part party_dummy
;
754 unsigned long long_dummy
;
756 if (mouse_position_hook
)
757 (*mouse_position_hook
) (&f
,
758 &lispy_dummy
, &party_dummy
,
767 XSET (lispy_dummy
, Lisp_Frame
, f
);
768 return Fcons (lispy_dummy
, Fcons (make_number (x
), make_number (y
)));
771 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
772 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
773 WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
775 Lisp_Object frame
, x
, y
;
777 CHECK_LIVE_FRAME (frame
, 0);
781 /* I think this should be done with a hook. */
782 #ifdef HAVE_X_WINDOWS
783 if (FRAME_X_P (XFRAME (frame
)))
784 /* Warping the mouse will cause enternotify and focus events. */
785 x_set_mouse_position (XFRAME (frame
), x
, y
);
792 /* ??? Can this be replaced with a Lisp function?
793 It is used in minibuf.c. Can we get rid of that?
794 Yes. All uses in minibuf.c are gone, and parallels to these
795 functions have been defined in frame.el. */
797 DEFUN ("frame-configuration", Fframe_configuration
, Sframe_configuration
,
799 "Return object describing current frame configuration.\n\
800 The frame configuration is the current mouse position and selected frame.\n\
801 This object can be given to `restore-frame-configuration'\n\
802 to restore this frame configuration.")
807 c
= Fmake_vector (make_number(4), Qnil
);
808 XVECTOR (c
)->contents
[0] = Fselected_frame();
809 if (mouse_position_hook
)
810 (*mouse_position_hook
) (&XVECTOR (c
)->contents
[1]
811 &XVECTOR (c
)->contents
[2],
812 &XVECTOR (c
)->contents
[3],
817 DEFUN ("restore-frame-configuration", Frestore_frame_configuration
,
818 Srestore_frame_configuration
,
820 "Restores frame configuration CONFIGURATION.")
824 Lisp_Object x_pos
, y_pos
, frame
;
826 CHECK_VECTOR (config
, 0);
827 if (XVECTOR (config
)->size
!= 3)
829 error ("Wrong size vector passed to restore-frame-configuration");
831 frame
= XVECTOR (config
)->contents
[0];
832 CHECK_LIVE_FRAME (frame
, 0);
834 Fselect_frame (frame
, Qnil
);
837 /* This seems to interfere with the frame selection mechanism. jla */
838 x_pos
= XVECTOR (config
)->contents
[2];
839 y_pos
= XVECTOR (config
)->contents
[3];
840 set_mouse_position (frame
, XINT (x_pos
), XINT (y_pos
));
847 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
849 "Make the frame FRAME visible (assuming it is an X-window).\n\
850 Also raises the frame so that nothing obscures it.\n\
851 If omitted, FRAME defaults to the currently selected frame.")
856 XSET (frame
, Lisp_Frame
, selected_frame
);
858 CHECK_LIVE_FRAME (frame
, 0);
860 /* I think this should be done with a hook. */
861 #ifdef HAVE_X_WINDOWS
862 if (FRAME_X_P (XFRAME (frame
)))
863 x_make_frame_visible (XFRAME (frame
));
869 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
871 "Make the frame FRAME invisible (assuming it is an X-window).\n\
872 If omitted, FRAME defaults to the currently selected frame.")
877 XSET (frame
, Lisp_Frame
, selected_frame
);
879 CHECK_LIVE_FRAME (frame
, 0);
881 /* I think this should be done with a hook. */
882 #ifdef HAVE_X_WINDOWS
883 if (FRAME_X_P (XFRAME (frame
)))
884 x_make_frame_invisible (XFRAME (frame
));
890 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
892 "Make the frame FRAME into an icon.\n\
893 If omitted, FRAME defaults to the currently selected frame.")
898 XSET (frame
, Lisp_Frame
, selected_frame
);
900 CHECK_LIVE_FRAME (frame
, 0);
902 /* I think this should be done with a hook. */
903 #ifdef HAVE_X_WINDOWS
904 if (FRAME_X_P (XFRAME (frame
)))
905 x_iconify_frame (XFRAME (frame
));
911 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
913 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
914 A frame that is not \"visible\" is not updated and, if it works through\n\
915 a window system, it may not show at all.\n\
916 Return the symbol `icon' if frame is visible only as an icon.")
920 CHECK_LIVE_FRAME (frame
, 0);
922 if (FRAME_VISIBLE_P (XFRAME (frame
)))
924 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
929 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
931 "Return a list of all frames now \"visible\" (being updated).")
934 Lisp_Object tail
, frame
;
939 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
941 frame
= XCONS (tail
)->car
;
942 if (XTYPE (frame
) != Lisp_Frame
)
945 if (FRAME_VISIBLE_P (f
))
946 value
= Fcons (frame
, value
);
952 DEFUN ("frame-to-front", Fframe_to_front
, Sframe_to_front
, 1, 1, 0,
953 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
954 If FRAME is invisible, make it visible.\n\
955 If Emacs is displaying on an ordinary terminal or some other device which\n\
956 doesn't support multiple overlapping frames, this function does nothing.")
960 CHECK_LIVE_FRAME (frame
, 0);
962 if (frame_raise_lower_hook
)
963 (*frame_raise_lower_hook
) (XFRAME (frame
), 1);
968 DEFUN ("frame-to-back", Fframe_to_back
, Sframe_to_back
, 1, 1, 0,
969 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
970 If Emacs is displaying on an ordinary terminal or some other device which\n\
971 doesn't support multiple overlapping frames, this function does nothing.")
975 CHECK_LIVE_FRAME (frame
, 0);
977 if (frame_raise_lower_hook
)
978 (*frame_raise_lower_hook
) (XFRAME (frame
), 0);
984 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
986 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
987 In other words, switch-frame events caused by events in FRAME will\n\
988 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
989 FOCUS-FRAME after reading an event typed at FRAME.\n\
991 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
992 cancelled, and the frame again receives its own keystrokes.\n\
994 Focus redirection is useful for temporarily redirecting keystrokes to\n\
995 a surrogate minibuffer frame when a frame doesn't have its own\n\
996 minibuffer window.\n\
998 A frame's focus redirection can be changed by select-frame. If frame\n\
999 FOO is selected, and then a different frame BAR is selected, any\n\
1000 frames redirecting their focus to FOO are shifted to redirect their\n\
1001 focus to BAR. This allows focus redirection to work properly when the\n\
1002 user switches from one frame to another using `select-window'.\n\
1004 This means that a frame whose focus is redirected to itself is treated\n\
1005 differently from a frame whose focus is redirected to nil; the former\n\
1006 is affected by select-frame, while the latter is not.\n\
1008 The redirection lasts until `redirect-frame-focus' is called to change it.")
1009 (frame
, focus_frame
)
1010 Lisp_Object frame
, focus_frame
;
1012 CHECK_LIVE_FRAME (frame
, 0);
1014 if (! NILP (focus_frame
))
1015 CHECK_LIVE_FRAME (focus_frame
, 1);
1017 XFRAME (frame
)->focus_frame
= focus_frame
;
1019 if (frame_rehighlight_hook
)
1020 (*frame_rehighlight_hook
) ();
1026 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 1, 1, 0,
1027 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1028 This returns nil if FRAME's focus is not redirected.\n\
1029 See `redirect-frame-focus'.")
1033 CHECK_LIVE_FRAME (frame
, 0);
1035 return FRAME_FOCUS_FRAME (XFRAME (frame
));
1041 get_frame_param (frame
, prop
)
1042 register struct frame
*frame
;
1045 register Lisp_Object tem
;
1047 tem
= Fassq (prop
, frame
->param_alist
);
1054 store_in_alist (alistptr
, prop
, val
)
1055 Lisp_Object
*alistptr
, val
;
1058 register Lisp_Object tem
;
1060 tem
= Fassq (prop
, *alistptr
);
1062 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
1068 store_frame_param (f
, prop
, val
)
1070 Lisp_Object prop
, val
;
1072 register Lisp_Object tem
;
1074 tem
= Fassq (prop
, f
->param_alist
);
1076 f
->param_alist
= Fcons (Fcons (prop
, val
), f
->param_alist
);
1080 if (EQ (prop
, Qminibuffer
)
1081 && XTYPE (val
) == Lisp_Window
)
1083 if (! MINI_WINDOW_P (XWINDOW (val
)))
1084 error ("Surrogate minibuffer windows must be minibuffer windows.");
1086 if (FRAME_HAS_MINIBUF_P (f
) || FRAME_MINIBUF_ONLY_P (f
))
1087 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
1089 /* Install the chosen minibuffer window, with proper buffer. */
1090 f
->minibuffer_window
= val
;
1094 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
1095 "Return the parameters-alist of frame FRAME.\n\
1096 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1097 The meaningful PARMs depend on the kind of frame.\n\
1098 If FRAME is omitted, return information on the currently selected frame.")
1105 if (EQ (frame
, Qnil
))
1109 CHECK_FRAME (frame
, 0);
1113 if (f
->display
.nothing
== 0)
1116 alist
= Fcopy_alist (f
->param_alist
);
1117 store_in_alist (&alist
, Qname
, f
->name
);
1118 store_in_alist (&alist
, Qheight
, make_number (f
->height
));
1119 store_in_alist (&alist
, Qwidth
, make_number (f
->width
));
1120 store_in_alist (&alist
, Qmodeline
, (f
->wants_modeline
? Qt
: Qnil
));
1121 store_in_alist (&alist
, Qminibuffer
,
1122 (! FRAME_HAS_MINIBUF_P (f
) ? Qnil
1123 : (FRAME_MINIBUF_ONLY_P (f
) ? Qonly
1124 : FRAME_MINIBUF_WINDOW (f
))));
1125 store_in_alist (&alist
, Qunsplittable
, (f
->no_split
? Qt
: Qnil
));
1127 /* I think this should be done with a hook. */
1128 #ifdef HAVE_X_WINDOWS
1130 x_report_frame_params (f
, &alist
);
1135 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
1136 Smodify_frame_parameters
, 2, 2, 0,
1137 "Modify the parameters of frame FRAME according to ALIST.\n\
1138 ALIST is an alist of parameters to change and their new values.\n\
1139 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1140 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1142 Lisp_Object frame
, alist
;
1145 register Lisp_Object tail
, elt
, prop
, val
;
1147 if (EQ (frame
, Qnil
))
1151 CHECK_LIVE_FRAME (frame
, 0);
1155 /* I think this should be done with a hook. */
1156 #ifdef HAVE_X_WINDOWS
1159 x_set_frame_parameters (f
, alist
);
1161 for (tail
= alist
; !EQ (tail
, Qnil
); tail
= Fcdr (tail
))
1166 x_set_frame_param (f
, prop
, val
, get_frame_param (f
, prop
));
1167 store_frame_param (f
, prop
, val
);
1177 /* This function isn't useful enough by itself to include; we need to
1178 add functions to allow the user to find the size of a font before
1179 this is actually useful. */
1181 DEFUN ("frame-pixel-size", Fframe_pixel_size
,
1182 Sframe_pixel_size
, 1, 1, 0,
1183 "Return a cons (width . height) of FRAME's size in pixels.")
1187 register struct frame
*f
;
1190 CHECK_LIVE_FRAME (frame
, 0);
1193 return Fcons (make_number (x_pixel_width (f
)),
1194 make_number (x_pixel_height (f
)));
1199 /* These functions have no C callers, and can be written nicely in lisp. */
1201 DEFUN ("frame-height", Fframe_height
, Sframe_height
, 0, 0, 0,
1202 "Return number of lines available for display on selected frame.")
1205 return make_number (FRAME_HEIGHT (selected_frame
));
1208 DEFUN ("frame-width", Fframe_width
, Sframe_width
, 0, 0, 0,
1209 "Return number of columns available for display on selected frame.")
1212 return make_number (FRAME_WIDTH (selected_frame
));
1216 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 3, 0,
1217 "Specify that the frame FRAME has LINES lines.\n\
1218 Optional third arg non-nil means that redisplay should use LINES lines\n\
1219 but that the idea of the actual height of the frame should not be changed.")
1220 (frame
, rows
, pretend
)
1221 Lisp_Object frame
, rows
, pretend
;
1223 register struct frame
*f
;
1225 CHECK_NUMBER (rows
, 0);
1230 CHECK_LIVE_FRAME (frame
, 0);
1234 /* I think this should be done with a hook. */
1235 #ifdef HAVE_X_WINDOWS
1238 if (XINT (rows
) != f
->width
)
1239 x_set_window_size (f
, f
->width
, XINT (rows
));
1243 change_frame_size (f
, XINT (rows
), 0, !NILP (pretend
), 0);
1247 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 3, 0,
1248 "Specify that the frame FRAME has COLS columns.\n\
1249 Optional third arg non-nil means that redisplay should use COLS columns\n\
1250 but that the idea of the actual width of the frame should not be changed.")
1251 (frame
, cols
, pretend
)
1252 Lisp_Object frame
, cols
, pretend
;
1254 register struct frame
*f
;
1255 CHECK_NUMBER (cols
, 0);
1260 CHECK_LIVE_FRAME (frame
, 0);
1264 /* I think this should be done with a hook. */
1265 #ifdef HAVE_X_WINDOWS
1268 if (XINT (cols
) != f
->width
)
1269 x_set_window_size (f
, XINT (cols
), f
->height
);
1273 change_frame_size (f
, 0, XINT (cols
), !NILP (pretend
), 0);
1277 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 3, 0,
1278 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1280 Lisp_Object frame
, cols
, rows
;
1282 register struct frame
*f
;
1285 CHECK_LIVE_FRAME (frame
, 0);
1286 CHECK_NUMBER (cols
, 2);
1287 CHECK_NUMBER (rows
, 1);
1290 /* I think this should be done with a hook. */
1291 #ifdef HAVE_X_WINDOWS
1294 if (XINT (rows
) != f
->height
|| XINT (cols
) != f
->width
)
1295 x_set_window_size (f
, XINT (cols
), XINT (rows
));
1299 change_frame_size (f
, XINT (rows
), XINT (cols
), 0, 0);
1304 DEFUN ("set-frame-position", Fset_frame_position
,
1305 Sset_frame_position
, 3, 3, 0,
1306 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
1307 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1308 the leftmost or bottommost position FRAME could occupy without going\n\
1310 (frame
, xoffset
, yoffset
)
1311 Lisp_Object frame
, xoffset
, yoffset
;
1313 register struct frame
*f
;
1316 CHECK_LIVE_FRAME (frame
, 0);
1317 CHECK_NUMBER (xoffset
, 1);
1318 CHECK_NUMBER (yoffset
, 2);
1321 /* I think this should be done with a hook. */
1322 #ifdef HAVE_X_WINDOWS
1324 x_set_offset (f
, XINT (xoffset
), XINT (yoffset
));
1332 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle
, Srubber_band_rectangle
,
1334 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1335 Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
1336 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1337 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1338 the mouse is not used.\n\
1339 Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1346 Lisp_Object nums
[4];
1349 CHECK_FRAME (frame
, 0);
1350 CHECK_STRING (name
, 1);
1351 CHECK_STRING (geo
, 2);
1353 switch (XFRAME (frame
)->output_method
)
1355 case output_x_window
:
1356 x_rubber_band (XFRAME (frame
), &vals
[0], &vals
[1], &vals
[2], &vals
[3],
1357 XSTRING (geo
)->data
, XSTRING (name
)->data
);
1364 for (i
= 0; i
< 4; i
++)
1365 XFASTINT (nums
[i
]) = vals
[i
];
1366 return Fcons (frame
, Flist (4, nums
));
1369 #endif /* not HAVE_X11 */
1371 choose_minibuf_frame ()
1373 /* For lowest-level minibuf, put it on currently selected frame
1374 if frame has a minibuffer. */
1376 if (minibuf_level
== 0
1377 && selected_frame
!= 0
1378 && !EQ (minibuf_window
, selected_frame
->minibuffer_window
))
1380 /* I don't think that any frames may validly have a null minibuffer
1382 if (NILP (selected_frame
->minibuffer_window
))
1385 Fset_window_buffer (selected_frame
->minibuffer_window
,
1386 XWINDOW (minibuf_window
)->buffer
);
1387 minibuf_window
= selected_frame
->minibuffer_window
;
1393 /*&&& init symbols here &&&*/
1394 Qframep
= intern ("framep");
1395 staticpro (&Qframep
);
1396 Qframe_live_p
= intern ("frame-live-p");
1397 staticpro (&Qframe_live_p
);
1398 Qheight
= intern ("height");
1399 staticpro (&Qheight
);
1400 Qicon
= intern ("icon");
1402 Qminibuffer
= intern ("minibuffer");
1403 staticpro (&Qminibuffer
);
1404 Qmodeline
= intern ("modeline");
1405 staticpro (&Qmodeline
);
1406 Qname
= intern ("name");
1408 Qonly
= intern ("only");
1410 Qunsplittable
= intern ("unsplittable");
1411 staticpro (&Qunsplittable
);
1412 Qwidth
= intern ("width");
1413 staticpro (&Qwidth
);
1417 staticpro (&Vframe_list
);
1419 DEFVAR_LISP ("terminal-frame", &Vterminal_frame
,
1420 "The initial frame-object, which represents Emacs's stdout.");
1422 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified
,
1423 "Non-nil if all of emacs is iconified and frame updates are not needed.");
1424 Vemacs_iconified
= Qnil
;
1426 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame
,
1427 "Minibufferless frames use this frame's minibuffer.\n\
1429 Emacs cannot create minibufferless frames unless this is set to an\n\
1430 appropriate surrogate.\n\
1432 Emacs consults this variable only when creating minibufferless\n\
1433 frames; once the frame is created, it sticks with its assigned\n\
1434 minibuffer, no matter what this variable is set to. This means that\n\
1435 this variable doesn't necessarily say anything meaningful about the\n\
1436 current set of frames, or where the minibuffer is currently being\n\
1438 Vdefault_minibuffer_frame
= Qnil
;
1440 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist
,
1441 "Alist of default values for frame creation.\n\
1442 These may be set in your init file, like this:\n\
1443 (setq default-frame-alist '((width . 80) (height . 55)))\n\
1444 These override values given in window system configuration data, like\n\
1445 X Windows' defaults database.\n\
1446 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1447 For values specific to the separate minibuffer frame, see\n\
1448 `minibuffer-frame-alist'.");
1449 Vdefault_frame_alist
= Qnil
;
1452 defsubr (&Sframe_live_p
);
1453 defsubr (&Sselect_frame
);
1454 defsubr (&Sselected_frame
);
1455 defsubr (&Swindow_frame
);
1456 defsubr (&Sframe_root_window
);
1457 defsubr (&Sframe_selected_window
);
1458 defsubr (&Sframe_list
);
1459 defsubr (&Snext_frame
);
1460 defsubr (&Sdelete_frame
);
1461 defsubr (&Smouse_position
);
1462 defsubr (&Sset_mouse_position
);
1464 defsubr (&Sframe_configuration
);
1465 defsubr (&Srestore_frame_configuration
);
1467 defsubr (&Smake_frame_visible
);
1468 defsubr (&Smake_frame_invisible
);
1469 defsubr (&Siconify_frame
);
1470 defsubr (&Sframe_visible_p
);
1471 defsubr (&Svisible_frame_list
);
1472 defsubr (&Sframe_to_front
);
1473 defsubr (&Sframe_to_back
);
1474 defsubr (&Sredirect_frame_focus
);
1475 defsubr (&Sframe_focus
);
1476 defsubr (&Sframe_parameters
);
1477 defsubr (&Smodify_frame_parameters
);
1479 defsubr (&Sframe_pixel_size
);
1480 defsubr (&Sframe_height
);
1481 defsubr (&Sframe_width
);
1483 defsubr (&Sset_frame_height
);
1484 defsubr (&Sset_frame_width
);
1485 defsubr (&Sset_frame_size
);
1486 defsubr (&Sset_frame_position
);
1488 defsubr (&Srubber_band_rectangle
);
1489 #endif /* HAVE_X11 */
1494 initial_define_lispy_key (global_map
, "switch-frame", "select-frame");
1497 #else /* not MULTI_FRAME */
1499 /* If we're not using multi-frame stuff, we still need to provide some
1500 support functions. */
1502 /* Unless this function is defined, providing set-frame-height and
1503 set-frame-width doesn't help compatibility any, since they both
1504 want this as their first argument. */
1505 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
1506 "Return the frame that is now selected.")
1514 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 3, 0,
1515 "Specify that the frame FRAME has LINES lines.\n\
1516 Optional third arg non-nil means that redisplay should use LINES lines\n\
1517 but that the idea of the actual height of the frame should not be changed.")
1518 (frame
, rows
, pretend
)
1519 Lisp_Object frame
, rows
, pretend
;
1521 CHECK_NUMBER (rows
, 0);
1523 change_frame_size (0, XINT (rows
), 0, !NILP (pretend
), 0);
1527 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 3, 0,
1528 "Specify that the frame FRAME has COLS columns.\n\
1529 Optional third arg non-nil means that redisplay should use COLS columns\n\
1530 but that the idea of the actual width of the frame should not be changed.")
1531 (frame
, cols
, pretend
)
1532 Lisp_Object frame
, cols
, pretend
;
1534 CHECK_NUMBER (cols
, 0);
1536 change_frame_size (0, 0, XINT (cols
), !NILP (pretend
), 0);
1540 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 3, 0,
1541 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1543 Lisp_Object frame
, cols
, rows
;
1545 CHECK_NUMBER (cols
, 2);
1546 CHECK_NUMBER (rows
, 1);
1548 change_frame_size (0, XINT (rows
), XINT (cols
), 0, 0);
1553 DEFUN ("frame-height", Fframe_height
, Sframe_height
, 0, 0, 0,
1554 "Return number of lines available for display on selected frame.")
1557 return make_number (FRAME_HEIGHT (selected_frame
));
1560 DEFUN ("frame-width", Fframe_width
, Sframe_width
, 0, 0, 0,
1561 "Return number of columns available for display on selected frame.")
1564 return make_number (FRAME_WIDTH (selected_frame
));
1567 /* These are for backward compatibility with Emacs 18. */
1569 DEFUN ("set-screen-height", Fset_screen_height
, Sset_screen_height
, 1, 2, 0,
1570 "Tell redisplay that the screen has LINES lines.\n\
1571 Optional second arg non-nil means that redisplay should use LINES lines\n\
1572 but that the idea of the actual height of the screen should not be changed.")
1574 Lisp_Object lines
, pretend
;
1576 CHECK_NUMBER (lines
, 0);
1578 change_frame_size (0, XINT (lines
), 0, !NILP (pretend
), 0);
1582 DEFUN ("set-screen-width", Fset_screen_width
, Sset_screen_width
, 1, 2, 0,
1583 "Tell redisplay that the screen has COLS columns.\n\
1584 Optional second arg non-nil means that redisplay should use COLS columns\n\
1585 but that the idea of the actual width of the screen should not be changed.")
1587 Lisp_Object cols
, pretend
;
1589 CHECK_NUMBER (cols
, 0);
1591 change_frame_size (0, 0, XINT (cols
), !NILP (pretend
), 0);
1597 defsubr (&Sset_frame_height
);
1598 defsubr (&Sset_frame_width
);
1599 defsubr (&Sset_frame_size
);
1600 defsubr (&Sset_screen_height
);
1601 defsubr (&Sset_screen_width
);
1602 defsubr (&Sframe_height
);
1603 Ffset (intern ("screen-height"), intern ("frame-height"));
1604 defsubr (&Sframe_width
);
1605 Ffset (intern ("screen-width"), intern ("frame-width"));
1612 #endif /* not MULTI_FRAME */