1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 #include "termhooks.h"
32 /* Evaluate this expression to rebuild the section of syms_of_frame
33 that initializes and staticpros the symbols declared below. Note
34 that Emacs 18 has a bug that keeps C-x C-e from being able to
35 evaluate this expression.
38 ;; Accumulate a list of the symbols we want to initialize from the
39 ;; declarations at the top of the file.
40 (goto-char (point-min))
41 (search-forward "/\*&&& symbols declared here &&&*\/\n")
43 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
45 (cons (buffer-substring (match-beginning 1) (match-end 1))
48 (setq symbol-list (nreverse symbol-list))
49 ;; Delete the section of syms_of_... where we initialize the symbols.
50 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
51 (let ((start (point)))
52 (while (looking-at "^ Q")
54 (kill-region start (point)))
55 ;; Write a new symbol initialization section.
57 (insert (format " %s = intern (\"" (car symbol-list)))
58 (let ((start (point)))
59 (insert (substring (car symbol-list) 1))
60 (subst-char-in-region start (point) ?_ ?-))
61 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
62 (setq symbol-list (cdr symbol-list)))))
65 /*&&& symbols declared here &&&*/
67 Lisp_Object Qframe_live_p
;
70 Lisp_Object Qminibuffer
;
71 Lisp_Object Qmodeline
;
74 Lisp_Object Qunsplittable
;
75 Lisp_Object Qmenu_bar_lines
;
81 Lisp_Object Qbuffer_predicate
;
84 Lisp_Object Vterminal_frame
;
85 Lisp_Object Vdefault_frame_alist
;
90 /*&&& init symbols here &&&*/
91 Qframep
= intern ("framep");
93 Qframe_live_p
= intern ("frame-live-p");
94 staticpro (&Qframe_live_p
);
95 Qheight
= intern ("height");
97 Qicon
= intern ("icon");
99 Qminibuffer
= intern ("minibuffer");
100 staticpro (&Qminibuffer
);
101 Qmodeline
= intern ("modeline");
102 staticpro (&Qmodeline
);
103 Qname
= intern ("name");
105 Qonly
= intern ("only");
107 Qunsplittable
= intern ("unsplittable");
108 staticpro (&Qunsplittable
);
109 Qmenu_bar_lines
= intern ("menu-bar-lines");
110 staticpro (&Qmenu_bar_lines
);
111 Qwidth
= intern ("width");
115 Qwin32
= intern ("win32");
119 Qvisible
= intern ("visible");
120 staticpro (&Qvisible
);
121 Qbuffer_predicate
= intern ("buffer-predicate");
122 staticpro (&Qbuffer_predicate
);
123 Qtitle
= intern ("title");
126 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist
,
127 "Alist of default values for frame creation.\n\
128 These may be set in your init file, like this:\n\
129 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
130 These override values given in window system configuration data,\n\
131 including X Windows' defaults database.\n\
132 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
133 For values specific to the separate minibuffer frame, see\n\
134 `minibuffer-frame-alist'.\n\
135 The `menu-bar-lines' element of the list controls whether new frames\n\
136 have menu bars; `menu-bar-mode' works by altering this element.");
137 Vdefault_frame_alist
= Qnil
;
141 set_menu_bar_lines_1 (window
, n
)
145 struct window
*w
= XWINDOW (window
);
147 XSETFASTINT (w
->last_modified
, 0);
148 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
149 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
151 /* Handle just the top child in a vertical split. */
152 if (!NILP (w
->vchild
))
153 set_menu_bar_lines_1 (w
->vchild
, n
);
155 /* Adjust all children in a horizontal split. */
156 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
158 w
= XWINDOW (window
);
159 set_menu_bar_lines_1 (window
, n
);
164 set_menu_bar_lines (f
, value
, oldval
)
166 Lisp_Object value
, oldval
;
169 int olines
= FRAME_MENU_BAR_LINES (f
);
171 /* Right now, menu bars don't work properly in minibuf-only frames;
172 most of the commands try to apply themselves to the minibuffer
173 frame itself, and get an error because you can't switch buffers
174 in or split the minibuffer window. */
175 if (FRAME_MINIBUF_ONLY_P (f
))
178 if (INTEGERP (value
))
179 nlines
= XINT (value
);
183 if (nlines
!= olines
)
185 windows_or_buffers_changed
++;
186 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
187 FRAME_MENU_BAR_LINES (f
) = nlines
;
188 set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
194 /* These help us bind and responding to switch-frame events. */
195 #include "commands.h"
196 #include "keyboard.h"
198 Lisp_Object Vemacs_iconified
;
199 Lisp_Object Vframe_list
;
201 extern Lisp_Object Vminibuffer_list
;
202 extern Lisp_Object
get_minibuffer ();
203 extern Lisp_Object
Fhandle_switch_frame ();
204 extern Lisp_Object
Fredirect_frame_focus ();
205 extern Lisp_Object
x_get_focus_frame ();
207 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
208 "Return non-nil if OBJECT is a frame.\n\
209 Value is t for a termcap frame (a character-only terminal),\n\
210 `x' for an Emacs frame that is really an X window,\n\
211 `pc' for a direct-write MS-DOS frame.\n\
212 See also `frame-live-p'.")
216 if (!FRAMEP (object
))
218 switch (XFRAME (object
)->output_method
)
222 case output_x_window
:
226 case output_msdos_raw
:
233 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
234 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
235 Value is nil if OBJECT is not a live frame. If object is a live\n\
236 frame, the return value indicates what sort of output device it is\n\
237 displayed on. Value is t for a termcap frame (a character-only\n\
238 terminal), `x' for an Emacs frame being displayed in an X window.")
242 return ((FRAMEP (object
)
243 && FRAME_LIVE_P (XFRAME (object
)))
253 register struct frame
*f
;
254 register Lisp_Object root_window
;
255 register Lisp_Object mini_window
;
256 register struct Lisp_Vector
*vec
;
259 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct frame
));
260 for (i
= 0; i
< VECSIZE (struct frame
); i
++)
261 XSETFASTINT (vec
->contents
[i
], 0);
262 vec
->size
= VECSIZE (struct frame
);
263 f
= (struct frame
*)vec
;
264 XSETFRAME (frame
, f
);
268 f
->current_glyphs
= 0;
269 f
->desired_glyphs
= 0;
271 f
->async_visible
= 0;
272 f
->output_data
.nothing
= 0;
274 f
->async_iconified
= 0;
275 f
->wants_modeline
= 1;
280 f
->has_minibuffer
= mini_p
;
281 f
->focus_frame
= Qnil
;
282 f
->explicit_name
= 0;
283 f
->can_have_scroll_bars
= 0;
284 f
->has_vertical_scroll_bars
= 0;
285 f
->param_alist
= Qnil
;
286 f
->scroll_bars
= Qnil
;
287 f
->condemned_scroll_bars
= Qnil
;
288 f
->face_alist
= Qnil
;
289 f
->menu_bar_items
= Qnil
;
290 f
->menu_bar_vector
= Qnil
;
291 f
->menu_bar_items_used
= 0;
292 f
->buffer_predicate
= Qnil
;
294 f
->kboard
= initial_kboard
;
299 root_window
= make_window ();
302 mini_window
= make_window ();
303 XWINDOW (root_window
)->next
= mini_window
;
304 XWINDOW (mini_window
)->prev
= root_window
;
305 XWINDOW (mini_window
)->mini_p
= Qt
;
306 XWINDOW (mini_window
)->frame
= frame
;
307 f
->minibuffer_window
= mini_window
;
312 XWINDOW (root_window
)->next
= Qnil
;
313 f
->minibuffer_window
= Qnil
;
316 XWINDOW (root_window
)->frame
= frame
;
319 just so that there is "something there."
320 Correct size will be set up later with change_frame_size. */
325 XSETFASTINT (XWINDOW (root_window
)->width
, 10);
326 XSETFASTINT (XWINDOW (root_window
)->height
, (mini_p
? 9 : 10));
330 XSETFASTINT (XWINDOW (mini_window
)->width
, 10);
331 XSETFASTINT (XWINDOW (mini_window
)->top
, 9);
332 XSETFASTINT (XWINDOW (mini_window
)->height
, 1);
335 /* Choose a buffer for the frame's root window. */
339 XWINDOW (root_window
)->buffer
= Qt
;
340 buf
= Fcurrent_buffer ();
341 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
342 a space), try to find another one. */
343 if (XSTRING (Fbuffer_name (buf
))->data
[0] == ' ')
344 buf
= Fother_buffer (buf
, Qnil
);
345 Fset_window_buffer (root_window
, buf
);
350 XWINDOW (mini_window
)->buffer
= Qt
;
351 Fset_window_buffer (mini_window
,
352 (NILP (Vminibuffer_list
)
354 : Fcar (Vminibuffer_list
)));
357 f
->root_window
= root_window
;
358 f
->selected_window
= root_window
;
359 /* Make sure this window seems more recently used than
360 a newly-created, never-selected window. */
361 XSETFASTINT (XWINDOW (f
->selected_window
)->use_time
, ++window_select_count
);
366 /* Make a frame using a separate minibuffer window on another frame.
367 MINI_WINDOW is the minibuffer window to use. nil means use the
368 default (the global minibuffer). */
371 make_frame_without_minibuffer (mini_window
, kb
, display
)
372 register Lisp_Object mini_window
;
376 register struct frame
*f
;
379 if (!NILP (mini_window
))
380 CHECK_LIVE_WINDOW (mini_window
, 0);
383 if (!NILP (mini_window
)
384 && XFRAME (XWINDOW (mini_window
)->frame
)->kboard
!= kb
)
385 error ("frame and minibuffer must be on the same display");
388 /* Make a frame containing just a root window. */
391 if (NILP (mini_window
))
393 /* Use default-minibuffer-frame if possible. */
394 if (!FRAMEP (kb
->Vdefault_minibuffer_frame
)
395 || ! FRAME_LIVE_P (XFRAME (kb
->Vdefault_minibuffer_frame
)))
397 Lisp_Object frame_dummy
;
399 XSETFRAME (frame_dummy
, f
);
400 GCPRO1 (frame_dummy
);
401 /* If there's no minibuffer frame to use, create one. */
402 kb
->Vdefault_minibuffer_frame
=
403 call1 (intern ("make-initial-minibuffer-frame"), display
);
407 mini_window
= XFRAME (kb
->Vdefault_minibuffer_frame
)->minibuffer_window
;
410 f
->minibuffer_window
= mini_window
;
412 /* Make the chosen minibuffer window display the proper minibuffer,
413 unless it is already showing a minibuffer. */
414 if (NILP (Fmemq (XWINDOW (mini_window
)->buffer
, Vminibuffer_list
)))
415 Fset_window_buffer (mini_window
,
416 (NILP (Vminibuffer_list
)
418 : Fcar (Vminibuffer_list
)));
422 /* Make a frame containing only a minibuffer window. */
425 make_minibuffer_frame ()
427 /* First make a frame containing just a root window, no minibuffer. */
429 register struct frame
*f
= make_frame (0);
430 register Lisp_Object mini_window
;
431 register Lisp_Object frame
;
433 XSETFRAME (frame
, f
);
438 f
->wants_modeline
= 0;
439 f
->has_minibuffer
= 1;
441 /* Now label the root window as also being the minibuffer.
442 Avoid infinite looping on the window chain by marking next pointer
445 mini_window
= f
->minibuffer_window
= f
->root_window
;
446 XWINDOW (mini_window
)->mini_p
= Qt
;
447 XWINDOW (mini_window
)->next
= Qnil
;
448 XWINDOW (mini_window
)->prev
= Qnil
;
449 XWINDOW (mini_window
)->frame
= frame
;
451 /* Put the proper buffer in that window. */
453 Fset_window_buffer (mini_window
,
454 (NILP (Vminibuffer_list
)
456 : Fcar (Vminibuffer_list
)));
460 /* Construct a frame that refers to the terminal (stdin and stdout). */
462 static int terminal_frame_count
;
465 make_terminal_frame ()
467 register struct frame
*f
;
474 initial_kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
475 init_kboard (initial_kboard
);
476 initial_kboard
->next_kboard
= all_kboards
;
477 all_kboards
= initial_kboard
;
481 /* The first call must initialize Vframe_list. */
482 if (! (NILP (Vframe_list
) || CONSP (Vframe_list
)))
487 XSETFRAME (frame
, f
);
488 Vframe_list
= Fcons (frame
, Vframe_list
);
490 terminal_frame_count
++;
491 if (terminal_frame_count
== 1)
493 f
->name
= build_string ("Emacs");
497 sprintf (name
, "Emacs-%d", terminal_frame_count
);
498 f
->name
= build_string (name
);
501 f
->visible
= 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
502 f
->async_visible
= 1; /* Don't let visible be cleared later. */
504 f
->output_data
.x
= &the_only_x_display
;
505 f
->output_method
= output_msdos_raw
;
506 init_frame_faces (f
);
507 #else /* not MSDOS */
508 f
->output_data
.nothing
= 1; /* Nonzero means frame isn't deleted. */
513 DEFUN ("make-terminal-frame", Fmake_terminal_frame
, Smake_terminal_frame
,
514 1, 1, 0, "Create an additional terminal frame.\n\
515 You can create multiple frames on a text-only terminal in this way.\n\
516 Only the selected terminal frame is actually displayed.\n\
517 This function takes one argument, an alist specifying frame parameters.\n\
518 In practice, generally you don't need to specify any parameters.\n\
519 Note that changing the size of one terminal frame automatically affects all.")
527 if (selected_frame
->output_method
!= output_msdos_raw
)
530 if (selected_frame
->output_method
!= output_termcap
)
531 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
534 f
= make_terminal_frame ();
535 change_frame_size (f
, FRAME_HEIGHT (selected_frame
),
536 FRAME_WIDTH (selected_frame
), 0, 0);
537 remake_frame_glyphs (f
);
539 XSETFRAME (frame
, f
);
540 Fmodify_frame_parameters (frame
, parms
);
541 f
->face_alist
= selected_frame
->face_alist
;
546 do_switch_frame (frame
, no_enter
, track
)
547 Lisp_Object frame
, no_enter
;
550 /* If FRAME is a switch-frame event, extract the frame we should
553 && EQ (XCONS (frame
)->car
, Qswitch_frame
)
554 && CONSP (XCONS (frame
)->cdr
))
555 frame
= XCONS (XCONS (frame
)->cdr
)->car
;
557 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
558 a switch-frame event to arrive after a frame is no longer live,
559 especially when deleting the initial frame during startup. */
560 CHECK_FRAME (frame
, 0);
561 if (! FRAME_LIVE_P (XFRAME (frame
)))
564 if (selected_frame
== XFRAME (frame
))
567 /* This is too greedy; it causes inappropriate focus redirection
568 that's hard to get rid of. */
570 /* If a frame's focus has been redirected toward the currently
571 selected frame, we should change the redirection to point to the
572 newly selected frame. This means that if the focus is redirected
573 from a minibufferless frame to a surrogate minibuffer frame, we
574 can use `other-window' to switch between all the frames using
575 that minibuffer frame, and the focus redirection will follow us
581 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
585 if (!FRAMEP (XCONS (tail
)->car
))
588 focus
= FRAME_FOCUS_FRAME (XFRAME (XCONS (tail
)->car
));
590 if (FRAMEP (focus
) && XFRAME (focus
) == selected_frame
)
591 Fredirect_frame_focus (XCONS (tail
)->car
, frame
);
595 /* Instead, apply it only to the frame we're pointing to. */
596 #ifdef HAVE_WINDOW_SYSTEM
597 if (track
&& (FRAME_WINDOW_P (XFRAME (frame
))))
599 Lisp_Object focus
, xfocus
;
601 xfocus
= x_get_focus_frame (XFRAME (frame
));
604 focus
= FRAME_FOCUS_FRAME (XFRAME (xfocus
));
605 if (FRAMEP (focus
) && XFRAME (focus
) == selected_frame
)
606 Fredirect_frame_focus (xfocus
, frame
);
609 #endif /* HAVE_X_WINDOWS */
612 selected_frame
= XFRAME (frame
);
613 if (! FRAME_MINIBUF_ONLY_P (selected_frame
))
614 last_nonminibuf_frame
= selected_frame
;
616 Fselect_window (XFRAME (frame
)->selected_window
);
618 /* We want to make sure that the next event generates a frame-switch
619 event to the appropriate frame. This seems kludgy to me, but
620 before you take it out, make sure that evaluating something like
621 (select-window (frame-root-window (new-frame))) doesn't end up
622 with your typing being interpreted in the new frame instead of
623 the one you're actually typing in. */
624 internal_last_event_frame
= Qnil
;
629 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
630 "Select the frame FRAME.\n\
631 Subsequent editing commands apply to its selected window.\n\
632 The selection of FRAME lasts until the next time the user does\n\
633 something to select a different frame, or until the next time this\n\
634 function is called.")
636 Lisp_Object frame
, no_enter
;
638 return do_switch_frame (frame
, no_enter
, 1);
642 DEFUN ("handle-switch-frame", Fhandle_switch_frame
, Shandle_switch_frame
, 1, 2, "e",
643 "Handle a switch-frame event EVENT.\n\
644 Switch-frame events are usually bound to this function.\n\
645 A switch-frame event tells Emacs that the window manager has requested\n\
646 that the user's events be directed to the frame mentioned in the event.\n\
647 This function selects the selected window of the frame of EVENT.\n\
649 If EVENT is frame object, handle it as if it were a switch-frame event\n\
652 Lisp_Object event
, no_enter
;
654 /* Preserve prefix arg that the command loop just cleared. */
655 current_kboard
->Vprefix_arg
= Vcurrent_prefix_arg
;
656 call1 (Vrun_hooks
, Qmouse_leave_buffer_hook
);
657 return do_switch_frame (event
, no_enter
, 0);
660 DEFUN ("ignore-event", Fignore_event
, Signore_event
, 0, 0, "",
661 "Do nothing, but preserve any prefix argument already specified.\n\
662 This is a suitable binding for iconify-frame and make-frame-visible.")
665 current_kboard
->Vprefix_arg
= Vcurrent_prefix_arg
;
669 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
670 "Return the frame that is now selected.")
674 XSETFRAME (tem
, selected_frame
);
678 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 1, 1, 0,
679 "Return the frame object that window WINDOW is on.")
683 CHECK_LIVE_WINDOW (window
, 0);
684 return XWINDOW (window
)->frame
;
687 DEFUN ("frame-first-window", Fframe_first_window
, Sframe_first_window
, 0, 1, 0,
688 "Returns the topmost, leftmost window of FRAME.\n\
689 If omitted, FRAME defaults to the currently selected frame.")
696 w
= selected_frame
->root_window
;
699 CHECK_LIVE_FRAME (frame
, 0);
700 w
= XFRAME (frame
)->root_window
;
702 while (NILP (XWINDOW (w
)->buffer
))
704 if (! NILP (XWINDOW (w
)->hchild
))
705 w
= XWINDOW (w
)->hchild
;
706 else if (! NILP (XWINDOW (w
)->vchild
))
707 w
= XWINDOW (w
)->vchild
;
714 DEFUN ("active-minibuffer-window", Factive_minibuffer_window
,
715 Sactive_minibuffer_window
, 0, 0, 0,
716 "Return the currently active minibuffer window, or nil if none.")
719 return minibuf_level
? minibuf_window
: Qnil
;
722 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
723 "Returns the root-window of FRAME.\n\
724 If omitted, FRAME defaults to the currently selected frame.")
729 XSETFRAME (frame
, selected_frame
);
731 CHECK_LIVE_FRAME (frame
, 0);
733 return XFRAME (frame
)->root_window
;
736 DEFUN ("frame-selected-window", Fframe_selected_window
,
737 Sframe_selected_window
, 0, 1, 0,
738 "Return the selected window of frame object FRAME.\n\
739 If omitted, FRAME defaults to the currently selected frame.")
744 XSETFRAME (frame
, selected_frame
);
746 CHECK_LIVE_FRAME (frame
, 0);
748 return XFRAME (frame
)->selected_window
;
751 DEFUN ("set-frame-selected-window", Fset_frame_selected_window
,
752 Sset_frame_selected_window
, 2, 2, 0,
753 "Set the selected window of frame object FRAME to WINDOW.\n\
754 If FRAME is nil, the selected frame is used.\n\
755 If FRAME is the selected frame, this makes WINDOW the selected window.")
757 Lisp_Object frame
, window
;
760 XSETFRAME (frame
, selected_frame
);
762 CHECK_LIVE_FRAME (frame
, 0);
764 CHECK_LIVE_WINDOW (window
, 1);
766 if (! EQ (frame
, WINDOW_FRAME (XWINDOW (window
))))
767 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
769 if (XFRAME (frame
) == selected_frame
)
770 return Fselect_window (window
);
772 return XFRAME (frame
)->selected_window
= window
;
775 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
777 "Return a list of all frames.")
780 return Fcopy_sequence (Vframe_list
);
783 /* Return the next frame in the frame list after FRAME.
784 If MINIBUF is nil, exclude minibuffer-only frames.
785 If MINIBUF is a window, include only its own frame
786 and any frame now using that window as the minibuffer.
787 If MINIBUF is `visible', include all visible frames.
788 If MINIBUF is 0, include all visible and iconified frames.
789 Otherwise, include all frames. */
792 next_frame (frame
, minibuf
)
799 /* There must always be at least one frame in Vframe_list. */
800 if (! CONSP (Vframe_list
))
803 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
804 forever. Forestall that. */
805 CHECK_LIVE_FRAME (frame
, 0);
808 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
812 f
= XCONS (tail
)->car
;
815 && FRAME_KBOARD (XFRAME (f
)) == FRAME_KBOARD (XFRAME (frame
)))
817 /* Decide whether this frame is eligible to be returned. */
819 /* If we've looped all the way around without finding any
820 eligible frames, return the original frame. */
824 /* Let minibuf decide if this frame is acceptable. */
827 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
830 else if (EQ (minibuf
, Qvisible
))
832 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
833 if (FRAME_VISIBLE_P (XFRAME (f
)))
836 else if (XFASTINT (minibuf
) == 0)
838 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
839 if (FRAME_VISIBLE_P (XFRAME (f
))
840 || FRAME_ICONIFIED_P (XFRAME (f
)))
843 else if (WINDOWP (minibuf
))
845 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
)
846 /* Check that F either is, or has forwarded its focus to,
848 && (EQ (WINDOW_FRAME (XWINDOW (minibuf
)), f
)
849 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
850 FRAME_FOCUS_FRAME (XFRAME (f
)))))
862 /* Return the previous frame in the frame list before FRAME.
863 If MINIBUF is nil, exclude minibuffer-only frames.
864 If MINIBUF is a window, include only its own frame
865 and any frame now using that window as the minibuffer.
866 If MINIBUF is `visible', include all visible frames.
867 If MINIBUF is 0, include all visible and iconified frames.
868 Otherwise, include all frames. */
871 prev_frame (frame
, minibuf
)
878 /* There must always be at least one frame in Vframe_list. */
879 if (! CONSP (Vframe_list
))
883 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
887 f
= XCONS (tail
)->car
;
891 if (EQ (frame
, f
) && !NILP (prev
))
894 if (FRAME_KBOARD (XFRAME (f
)) == FRAME_KBOARD (XFRAME (frame
)))
896 /* Decide whether this frame is eligible to be returned,
897 according to minibuf. */
900 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
903 else if (WINDOWP (minibuf
))
905 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
)
906 /* Check that F either is, or has forwarded its focus to,
908 && (EQ (WINDOW_FRAME (XWINDOW (minibuf
)), f
)
909 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
910 FRAME_FOCUS_FRAME (XFRAME (f
)))))
913 else if (EQ (minibuf
, Qvisible
))
915 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
916 if (FRAME_VISIBLE_P (XFRAME (f
)))
919 else if (XFASTINT (minibuf
) == 0)
921 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
922 if (FRAME_VISIBLE_P (XFRAME (f
))
923 || FRAME_ICONIFIED_P (XFRAME (f
)))
931 /* We've scanned the entire list. */
933 /* We went through the whole frame list without finding a single
934 acceptable frame. Return the original frame. */
937 /* There were no acceptable frames in the list before FRAME; otherwise,
938 we would have returned directly from the loop. Since PREV is the last
939 acceptable frame in the list, return it. */
944 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
945 "Return the next frame in the frame list after FRAME.\n\
946 It considers only frames on the same terminal as FRAME.\n\
947 By default, skip minibuffer-only frames.\n\
948 If omitted, FRAME defaults to the selected frame.\n\
949 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
950 If MINIFRAME is a window, include only its own frame\n\
951 and any frame now using that window as the minibuffer.\n\
952 If MINIFRAME is `visible', include all visible frames.\n\
953 If MINIFRAME is 0, include all visible and iconified frames.\n\
954 Otherwise, include all frames.")
956 Lisp_Object frame
, miniframe
;
961 XSETFRAME (frame
, selected_frame
);
963 CHECK_LIVE_FRAME (frame
, 0);
965 return next_frame (frame
, miniframe
);
968 DEFUN ("previous-frame", Fprevious_frame
, Sprevious_frame
, 0, 2, 0,
969 "Return the previous frame in the frame list before FRAME.\n\
970 It considers only frames on the same terminal as FRAME.\n\
971 By default, skip minibuffer-only frames.\n\
972 If omitted, FRAME defaults to the selected frame.\n\
973 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
974 If MINIFRAME is a window, include only its own frame\n\
975 and any frame now using that window as the minibuffer.\n\
976 If MINIFRAME is `visible', include all visible frames.\n\
977 If MINIFRAME is 0, include all visible and iconified frames.\n\
978 Otherwise, include all frames.")
980 Lisp_Object frame
, miniframe
;
985 XSETFRAME (frame
, selected_frame
);
987 CHECK_LIVE_FRAME (frame
, 0);
989 return prev_frame (frame
, miniframe
);
992 /* Return 1 if it is ok to delete frame F;
993 0 if all frames aside from F are invisible.
994 (Exception: if F is the terminal frame, and we are using X, return 1.) */
997 other_visible_frames (f
)
1000 /* We know the selected frame is visible,
1001 so if F is some other frame, it can't be the sole visible one. */
1002 if (f
== selected_frame
)
1007 for (frames
= Vframe_list
;
1009 frames
= XCONS (frames
)->cdr
)
1013 this = XCONS (frames
)->car
;
1014 /* Verify that the frame's window still exists
1015 and we can still talk to it. And note any recent change
1017 #ifdef HAVE_WINDOW_SYSTEM
1018 if (FRAME_WINDOW_P (XFRAME (this)))
1020 x_sync (XFRAME (this));
1021 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1025 if (FRAME_VISIBLE_P (XFRAME (this))
1026 || FRAME_ICONIFIED_P (XFRAME (this))
1027 /* Allow deleting the terminal frame when at least
1028 one X frame exists! */
1029 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f
)))
1037 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 2, "",
1038 "Delete FRAME, permanently eliminating it from use.\n\
1039 If omitted, FRAME defaults to the selected frame.\n\
1040 A frame may not be deleted if its minibuffer is used by other frames.\n\
1041 Normally, you may not delete a frame if all other frames are invisible,\n\
1042 but if the second optional argument FORCE is non-nil, you may do so.")
1044 Lisp_Object frame
, force
;
1047 int minibuffer_selected
;
1049 if (EQ (frame
, Qnil
))
1052 XSETFRAME (frame
, f
);
1056 CHECK_FRAME (frame
, 0);
1060 if (! FRAME_LIVE_P (f
))
1063 if (NILP (force
) && !other_visible_frames (f
))
1064 error ("Attempt to delete the sole visible or iconified frame");
1066 /* Does this frame have a minibuffer, and is it the surrogate
1067 minibuffer for any other frame? */
1068 if (FRAME_HAS_MINIBUF_P (XFRAME (frame
)))
1072 for (frames
= Vframe_list
;
1074 frames
= XCONS (frames
)->cdr
)
1077 this = XCONS (frames
)->car
;
1079 if (! EQ (this, frame
)
1081 WINDOW_FRAME (XWINDOW
1082 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1083 error ("Attempt to delete a surrogate minibuffer frame");
1087 minibuffer_selected
= EQ (minibuf_window
, selected_window
);
1089 /* Don't let the frame remain selected. */
1090 if (f
== selected_frame
)
1092 Lisp_Object tail
, frame1
;
1094 /* Look for another visible frame on the same terminal. */
1095 frame1
= next_frame (frame
, Qvisible
);
1097 /* If there is none, find *some* other frame. */
1098 if (NILP (frame1
) || EQ (frame1
, frame
))
1100 FOR_EACH_FRAME (tail
, frame1
)
1102 if (! EQ (frame
, frame1
))
1107 do_switch_frame (frame1
, Qnil
, 0);
1110 /* Don't allow minibuf_window to remain on a deleted frame. */
1111 if (EQ (f
->minibuffer_window
, minibuf_window
))
1113 Fset_window_buffer (selected_frame
->minibuffer_window
,
1114 XWINDOW (minibuf_window
)->buffer
);
1115 minibuf_window
= selected_frame
->minibuffer_window
;
1117 /* If the dying minibuffer window was selected,
1118 select the new one. */
1119 if (minibuffer_selected
)
1120 Fselect_window (minibuf_window
);
1123 /* Clear any X selections for this frame. */
1124 #ifdef HAVE_X_WINDOWS
1126 x_clear_frame_selections (f
);
1129 /* Mark all the windows that used to be on FRAME as deleted, and then
1130 remove the reference to them. */
1131 delete_all_subwindows (XWINDOW (f
->root_window
));
1132 f
->root_window
= Qnil
;
1134 Vframe_list
= Fdelq (frame
, Vframe_list
);
1135 FRAME_SET_VISIBLE (f
, 0);
1139 if (FRAME_CURRENT_GLYPHS (f
))
1140 free_frame_glyphs (f
, FRAME_CURRENT_GLYPHS (f
));
1141 if (FRAME_DESIRED_GLYPHS (f
))
1142 free_frame_glyphs (f
, FRAME_DESIRED_GLYPHS (f
));
1143 if (FRAME_TEMP_GLYPHS (f
))
1144 free_frame_glyphs (f
, FRAME_TEMP_GLYPHS (f
));
1145 if (FRAME_INSERT_COST (f
))
1146 free (FRAME_INSERT_COST (f
));
1147 if (FRAME_DELETEN_COST (f
))
1148 free (FRAME_DELETEN_COST (f
));
1149 if (FRAME_INSERTN_COST (f
))
1150 free (FRAME_INSERTN_COST (f
));
1151 if (FRAME_DELETE_COST (f
))
1152 free (FRAME_DELETE_COST (f
));
1154 /* Since some events are handled at the interrupt level, we may get
1155 an event for f at any time; if we zero out the frame's display
1156 now, then we may trip up the event-handling code. Instead, we'll
1157 promise that the display of the frame must be valid until we have
1158 called the window-system-dependent frame destruction routine. */
1160 /* I think this should be done with a hook. */
1161 #ifdef HAVE_WINDOW_SYSTEM
1162 if (FRAME_WINDOW_P (f
))
1163 x_destroy_window (f
);
1166 f
->output_data
.nothing
= 0;
1168 /* If we've deleted the last_nonminibuf_frame, then try to find
1170 if (f
== last_nonminibuf_frame
)
1174 last_nonminibuf_frame
= 0;
1176 for (frames
= Vframe_list
;
1178 frames
= XCONS (frames
)->cdr
)
1180 f
= XFRAME (XCONS (frames
)->car
);
1181 if (!FRAME_MINIBUF_ONLY_P (f
))
1183 last_nonminibuf_frame
= f
;
1189 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1190 find another one. Prefer minibuffer-only frames, but also notice
1191 frames with other windows. */
1192 if (EQ (frame
, FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
))
1196 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1197 Lisp_Object frame_with_minibuf
;
1198 /* Some frame we found on the same kboard, or nil if there are none. */
1199 Lisp_Object frame_on_same_kboard
;
1201 frame_on_same_kboard
= Qnil
;
1202 frame_with_minibuf
= Qnil
;
1204 for (frames
= Vframe_list
;
1206 frames
= XCONS (frames
)->cdr
)
1211 this = XCONS (frames
)->car
;
1216 /* Consider only frames on the same kboard
1217 and only those with minibuffers. */
1218 if (FRAME_KBOARD (f
) == FRAME_KBOARD (f1
)
1219 && FRAME_HAS_MINIBUF_P (f1
))
1221 frame_with_minibuf
= this;
1222 if (FRAME_MINIBUF_ONLY_P (f1
))
1226 if (FRAME_KBOARD (f
) == FRAME_KBOARD (f1
))
1227 frame_on_same_kboard
= this;
1230 if (!NILP (frame_on_same_kboard
))
1232 /* We know that there must be some frame with a minibuffer out
1233 there. If this were not true, all of the frames present
1234 would have to be minibufferless, which implies that at some
1235 point their minibuffer frames must have been deleted, but
1236 that is prohibited at the top; you can't delete surrogate
1237 minibuffer frames. */
1238 if (NILP (frame_with_minibuf
))
1241 FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
= frame_with_minibuf
;
1244 /* No frames left on this kboard--say no minibuffer either. */
1245 FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
= Qnil
;
1251 /* Return mouse position in character cell units. */
1253 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
1254 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1255 The position is given in character cells, where (0, 0) is the\n\
1256 upper-left corner.\n\
1257 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1258 to read the mouse position, it returns the selected frame for FRAME\n\
1259 and nil for X and Y.")
1263 Lisp_Object lispy_dummy
;
1264 enum scroll_bar_part party_dummy
;
1267 unsigned long long_dummy
;
1273 /* It's okay for the hook to refrain from storing anything. */
1274 if (mouse_position_hook
)
1275 (*mouse_position_hook
) (&f
, 0,
1276 &lispy_dummy
, &party_dummy
,
1283 pixel_to_glyph_coords (f
, col
, row
, &col
, &row
, NULL
, 1);
1288 XSETFRAME (lispy_dummy
, f
);
1289 return Fcons (lispy_dummy
, Fcons (x
, y
));
1292 DEFUN ("mouse-pixel-position", Fmouse_pixel_position
,
1293 Smouse_pixel_position
, 0, 0, 0,
1294 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1295 The position is given in pixel units, where (0, 0) is the\n\
1296 upper-left corner.\n\
1297 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1298 to read the mouse position, it returns the selected frame for FRAME\n\
1299 and nil for X and Y.")
1303 Lisp_Object lispy_dummy
;
1304 enum scroll_bar_part party_dummy
;
1307 unsigned long long_dummy
;
1313 /* It's okay for the hook to refrain from storing anything. */
1314 if (mouse_position_hook
)
1315 (*mouse_position_hook
) (&f
, 0,
1316 &lispy_dummy
, &party_dummy
,
1320 XSETFRAME (lispy_dummy
, f
);
1321 return Fcons (lispy_dummy
, Fcons (x
, y
));
1324 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
1325 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1326 Note, this is a no-op for an X frame that is not visible.\n\
1327 If you have just created a frame, you must wait for it to become visible\n\
1328 before calling this function on it, like this.\n\
1329 (while (not (frame-visible-p frame)) (sleep-for .5))")
1331 Lisp_Object frame
, x
, y
;
1333 CHECK_LIVE_FRAME (frame
, 0);
1334 CHECK_NUMBER (x
, 2);
1335 CHECK_NUMBER (y
, 1);
1337 /* I think this should be done with a hook. */
1338 #ifdef HAVE_WINDOW_SYSTEM
1339 if (FRAME_WINDOW_P (XFRAME (frame
)))
1340 /* Warping the mouse will cause enternotify and focus events. */
1341 x_set_mouse_position (XFRAME (frame
), x
, y
);
1343 #if defined (MSDOS) && defined (HAVE_MOUSE)
1344 if (FRAME_MSDOS_P (XFRAME (frame
)))
1346 Fselect_frame (frame
, Qnil
);
1347 mouse_moveto (XINT (x
), XINT (y
));
1355 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position
,
1356 Sset_mouse_pixel_position
, 3, 3, 0,
1357 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1358 Note, this is a no-op for an X frame that is not visible.\n\
1359 If you have just created a frame, you must wait for it to become visible\n\
1360 before calling this function on it, like this.\n\
1361 (while (not (frame-visible-p frame)) (sleep-for .5))")
1363 Lisp_Object frame
, x
, y
;
1365 CHECK_LIVE_FRAME (frame
, 0);
1366 CHECK_NUMBER (x
, 2);
1367 CHECK_NUMBER (y
, 1);
1369 /* I think this should be done with a hook. */
1370 #ifdef HAVE_WINDOW_SYSTEM
1371 if (FRAME_WINDOW_P (XFRAME (frame
)))
1372 /* Warping the mouse will cause enternotify and focus events. */
1373 x_set_mouse_pixel_position (XFRAME (frame
), x
, y
);
1375 #if defined (MSDOS) && defined (HAVE_MOUSE)
1376 if (FRAME_MSDOS_P (XFRAME (frame
)))
1378 Fselect_frame (frame
, Qnil
);
1379 mouse_moveto (XINT (x
), XINT (y
));
1387 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
1389 "Make the frame FRAME visible (assuming it is an X-window).\n\
1390 If omitted, FRAME defaults to the currently selected frame.")
1395 XSETFRAME (frame
, selected_frame
);
1397 CHECK_LIVE_FRAME (frame
, 0);
1399 /* I think this should be done with a hook. */
1400 #ifdef HAVE_WINDOW_SYSTEM
1401 if (FRAME_WINDOW_P (XFRAME (frame
)))
1403 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
1404 x_make_frame_visible (XFRAME (frame
));
1408 /* Make menu bar update for the Buffers and Frams menus. */
1409 windows_or_buffers_changed
++;
1414 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
1416 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1417 If omitted, FRAME defaults to the currently selected frame.\n\
1418 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1419 but if the second optional argument FORCE is non-nil, you may do so.")
1421 Lisp_Object frame
, force
;
1424 XSETFRAME (frame
, selected_frame
);
1426 CHECK_LIVE_FRAME (frame
, 0);
1428 if (NILP (force
) && !other_visible_frames (XFRAME (frame
)))
1429 error ("Attempt to make invisible the sole visible or iconified frame");
1431 #if 0 /* This isn't logically necessary, and it can do GC. */
1432 /* Don't let the frame remain selected. */
1433 if (XFRAME (frame
) == selected_frame
)
1434 do_switch_frame (next_frame (frame
, Qt
), Qnil
, 0)
1437 /* Don't allow minibuf_window to remain on a deleted frame. */
1438 if (EQ (XFRAME (frame
)->minibuffer_window
, minibuf_window
))
1440 Fset_window_buffer (selected_frame
->minibuffer_window
,
1441 XWINDOW (minibuf_window
)->buffer
);
1442 minibuf_window
= selected_frame
->minibuffer_window
;
1445 /* I think this should be done with a hook. */
1446 #ifdef HAVE_WINDOW_SYSTEM
1447 if (FRAME_WINDOW_P (XFRAME (frame
)))
1448 x_make_frame_invisible (XFRAME (frame
));
1451 /* Make menu bar update for the Buffers and Frams menus. */
1452 windows_or_buffers_changed
++;
1457 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
1459 "Make the frame FRAME into an icon.\n\
1460 If omitted, FRAME defaults to the currently selected frame.")
1465 XSETFRAME (frame
, selected_frame
);
1467 CHECK_LIVE_FRAME (frame
, 0);
1469 #if 0 /* This isn't logically necessary, and it can do GC. */
1470 /* Don't let the frame remain selected. */
1471 if (XFRAME (frame
) == selected_frame
)
1472 Fhandle_switch_frame (next_frame (frame
, Qt
), Qnil
);
1475 /* Don't allow minibuf_window to remain on a deleted frame. */
1476 if (EQ (XFRAME (frame
)->minibuffer_window
, minibuf_window
))
1478 Fset_window_buffer (selected_frame
->minibuffer_window
,
1479 XWINDOW (minibuf_window
)->buffer
);
1480 minibuf_window
= selected_frame
->minibuffer_window
;
1483 /* I think this should be done with a hook. */
1484 #ifdef HAVE_WINDOW_SYSTEM
1485 if (FRAME_WINDOW_P (XFRAME (frame
)))
1486 x_iconify_frame (XFRAME (frame
));
1489 /* Make menu bar update for the Buffers and Frams menus. */
1490 windows_or_buffers_changed
++;
1495 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
1497 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1498 A frame that is not \"visible\" is not updated and, if it works through\n\
1499 a window system, it may not show at all.\n\
1500 Return the symbol `icon' if frame is visible only as an icon.")
1504 CHECK_LIVE_FRAME (frame
, 0);
1506 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
1508 if (FRAME_VISIBLE_P (XFRAME (frame
)))
1510 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
1515 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
1517 "Return a list of all frames now \"visible\" (being updated).")
1520 Lisp_Object tail
, frame
;
1525 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1527 frame
= XCONS (tail
)->car
;
1528 if (!FRAMEP (frame
))
1531 if (FRAME_VISIBLE_P (f
))
1532 value
= Fcons (frame
, value
);
1538 DEFUN ("raise-frame", Fraise_frame
, Sraise_frame
, 0, 1, "",
1539 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1540 If FRAME is invisible, make it visible.\n\
1541 If you don't specify a frame, the selected frame is used.\n\
1542 If Emacs is displaying on an ordinary terminal or some other device which\n\
1543 doesn't support multiple overlapping frames, this function does nothing.")
1548 XSETFRAME (frame
, selected_frame
);
1550 CHECK_LIVE_FRAME (frame
, 0);
1552 /* Do like the documentation says. */
1553 Fmake_frame_visible (frame
);
1555 if (frame_raise_lower_hook
)
1556 (*frame_raise_lower_hook
) (XFRAME (frame
), 1);
1561 /* Should we have a corresponding function called Flower_Power? */
1562 DEFUN ("lower-frame", Flower_frame
, Slower_frame
, 0, 1, "",
1563 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1564 If you don't specify a frame, the selected frame is used.\n\
1565 If Emacs is displaying on an ordinary terminal or some other device which\n\
1566 doesn't support multiple overlapping frames, this function does nothing.")
1571 XSETFRAME (frame
, selected_frame
);
1573 CHECK_LIVE_FRAME (frame
, 0);
1575 if (frame_raise_lower_hook
)
1576 (*frame_raise_lower_hook
) (XFRAME (frame
), 0);
1582 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
1584 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1585 In other words, switch-frame events caused by events in FRAME will\n\
1586 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1587 FOCUS-FRAME after reading an event typed at FRAME.\n\
1589 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1590 cancelled, and the frame again receives its own keystrokes.\n\
1592 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1593 a surrogate minibuffer frame when a frame doesn't have its own\n\
1594 minibuffer window.\n\
1596 A frame's focus redirection can be changed by select-frame. If frame\n\
1597 FOO is selected, and then a different frame BAR is selected, any\n\
1598 frames redirecting their focus to FOO are shifted to redirect their\n\
1599 focus to BAR. This allows focus redirection to work properly when the\n\
1600 user switches from one frame to another using `select-window'.\n\
1602 This means that a frame whose focus is redirected to itself is treated\n\
1603 differently from a frame whose focus is redirected to nil; the former\n\
1604 is affected by select-frame, while the latter is not.\n\
1606 The redirection lasts until `redirect-frame-focus' is called to change it.")
1607 (frame
, focus_frame
)
1608 Lisp_Object frame
, focus_frame
;
1610 /* Note that we don't check for a live frame here. It's reasonable
1611 to redirect the focus of a frame you're about to delete, if you
1612 know what other frame should receive those keystrokes. */
1613 CHECK_FRAME (frame
, 0);
1615 if (! NILP (focus_frame
))
1616 CHECK_LIVE_FRAME (focus_frame
, 1);
1618 XFRAME (frame
)->focus_frame
= focus_frame
;
1620 /* I think this should be done with a hook. */
1621 #ifdef HAVE_WINDOW_SYSTEM
1622 if (!NILP (focus_frame
) && ! EQ (focus_frame
, frame
)
1623 && (FRAME_WINDOW_P (XFRAME (focus_frame
))))
1624 Ffocus_frame (focus_frame
);
1627 if (frame_rehighlight_hook
)
1628 (*frame_rehighlight_hook
) (XFRAME (frame
));
1634 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 1, 1, 0,
1635 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1636 This returns nil if FRAME's focus is not redirected.\n\
1637 See `redirect-frame-focus'.")
1641 CHECK_LIVE_FRAME (frame
, 0);
1643 return FRAME_FOCUS_FRAME (XFRAME (frame
));
1648 /* Return the value of frame parameter PROP in frame FRAME. */
1651 get_frame_param (frame
, prop
)
1652 register struct frame
*frame
;
1655 register Lisp_Object tem
;
1657 tem
= Fassq (prop
, frame
->param_alist
);
1663 /* Return the buffer-predicate of the selected frame. */
1666 frame_buffer_predicate ()
1668 return selected_frame
->buffer_predicate
;
1671 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1672 If the alist already has an element for PROP, we change it. */
1675 store_in_alist (alistptr
, prop
, val
)
1676 Lisp_Object
*alistptr
, val
;
1679 register Lisp_Object tem
;
1681 tem
= Fassq (prop
, *alistptr
);
1683 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
1689 store_frame_param (f
, prop
, val
)
1691 Lisp_Object prop
, val
;
1693 register Lisp_Object tem
;
1695 tem
= Fassq (prop
, f
->param_alist
);
1697 f
->param_alist
= Fcons (Fcons (prop
, val
), f
->param_alist
);
1701 if (EQ (prop
, Qbuffer_predicate
))
1702 f
->buffer_predicate
= val
;
1704 if (! FRAME_WINDOW_P (f
))
1705 if (EQ (prop
, Qmenu_bar_lines
))
1706 set_menu_bar_lines (f
, val
, make_number (FRAME_MENU_BAR_LINES (f
)));
1708 if (EQ (prop
, Qminibuffer
) && WINDOWP (val
))
1710 if (! MINI_WINDOW_P (XWINDOW (val
)))
1711 error ("Surrogate minibuffer windows must be minibuffer windows.");
1713 if (FRAME_HAS_MINIBUF_P (f
) || FRAME_MINIBUF_ONLY_P (f
))
1714 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
1716 /* Install the chosen minibuffer window, with proper buffer. */
1717 f
->minibuffer_window
= val
;
1721 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
1722 "Return the parameters-alist of frame FRAME.\n\
1723 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1724 The meaningful PARMs depend on the kind of frame.\n\
1725 If FRAME is omitted, return information on the currently selected frame.")
1733 if (EQ (frame
, Qnil
))
1737 CHECK_FRAME (frame
, 0);
1741 if (!FRAME_LIVE_P (f
))
1744 alist
= Fcopy_alist (f
->param_alist
);
1746 if (FRAME_MSDOS_P (f
))
1748 static char *colornames
[16] =
1750 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1751 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1752 "lightred", "lightmagenta", "yellow", "white"
1754 store_in_alist (&alist
, intern ("foreground-color"),
1755 build_string (colornames
[FRAME_FOREGROUND_PIXEL (f
)]));
1756 store_in_alist (&alist
, intern ("background-color"),
1757 build_string (colornames
[FRAME_BACKGROUND_PIXEL (f
)]));
1759 store_in_alist (&alist
, intern ("font"), build_string ("default"));
1761 store_in_alist (&alist
, Qname
, f
->name
);
1762 height
= (FRAME_NEW_HEIGHT (f
) ? FRAME_NEW_HEIGHT (f
) : FRAME_HEIGHT (f
));
1763 store_in_alist (&alist
, Qheight
, make_number (height
));
1764 width
= (FRAME_NEW_WIDTH (f
) ? FRAME_NEW_WIDTH (f
) : FRAME_WIDTH (f
));
1765 store_in_alist (&alist
, Qwidth
, make_number (width
));
1766 store_in_alist (&alist
, Qmodeline
, (FRAME_WANTS_MODELINE_P (f
) ? Qt
: Qnil
));
1767 store_in_alist (&alist
, Qminibuffer
,
1768 (! FRAME_HAS_MINIBUF_P (f
) ? Qnil
1769 : FRAME_MINIBUF_ONLY_P (f
) ? Qonly
1770 : FRAME_MINIBUF_WINDOW (f
)));
1771 store_in_alist (&alist
, Qunsplittable
, (FRAME_NO_SPLIT_P (f
) ? Qt
: Qnil
));
1773 /* I think this should be done with a hook. */
1774 #ifdef HAVE_WINDOW_SYSTEM
1775 if (FRAME_WINDOW_P (f
))
1776 x_report_frame_params (f
, &alist
);
1780 /* This ought to be correct in f->param_alist for an X frame. */
1782 XSETFASTINT (lines
, FRAME_MENU_BAR_LINES (f
));
1783 store_in_alist (&alist
, Qmenu_bar_lines
, lines
);
1788 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
1789 Smodify_frame_parameters
, 2, 2, 0,
1790 "Modify the parameters of frame FRAME according to ALIST.\n\
1791 ALIST is an alist of parameters to change and their new values.\n\
1792 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1793 The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1795 Lisp_Object frame
, alist
;
1798 register Lisp_Object tail
, elt
, prop
, val
;
1800 if (EQ (frame
, Qnil
))
1804 CHECK_LIVE_FRAME (frame
, 0);
1808 /* I think this should be done with a hook. */
1809 #ifdef HAVE_WINDOW_SYSTEM
1810 if (FRAME_WINDOW_P (f
))
1811 x_set_frame_parameters (f
, alist
);
1815 if (FRAME_MSDOS_P (f
))
1816 IT_set_frame_parameters (f
, alist
);
1819 for (tail
= alist
; !EQ (tail
, Qnil
); tail
= Fcdr (tail
))
1824 store_frame_param (f
, prop
, val
);
1830 DEFUN ("frame-char-height", Fframe_char_height
, Sframe_char_height
,
1832 "Height in pixels of a line in the font in frame FRAME.\n\
1833 If FRAME is omitted, the selected frame is used.\n\
1834 For a terminal frame, the value is always 1.")
1844 CHECK_FRAME (frame
, 0);
1848 #ifdef HAVE_WINDOW_SYSTEM
1849 if (FRAME_WINDOW_P (f
))
1850 return make_number (x_char_height (f
));
1853 return make_number (1);
1857 DEFUN ("frame-char-width", Fframe_char_width
, Sframe_char_width
,
1859 "Width in pixels of characters in the font in frame FRAME.\n\
1860 If FRAME is omitted, the selected frame is used.\n\
1861 The width is the same for all characters, because\n\
1862 currently Emacs supports only fixed-width fonts.\n\
1863 For a terminal screen, the value is always 1.")
1873 CHECK_FRAME (frame
, 0);
1877 #ifdef HAVE_WINDOW_SYSTEM
1878 if (FRAME_WINDOW_P (f
))
1879 return make_number (x_char_width (f
));
1882 return make_number (1);
1885 DEFUN ("frame-pixel-height", Fframe_pixel_height
,
1886 Sframe_pixel_height
, 0, 1, 0,
1887 "Return a FRAME's height in pixels.\n\
1888 For a terminal frame, the result really gives the height in characters.\n\
1889 If FRAME is omitted, the selected frame is used.")
1899 CHECK_FRAME (frame
, 0);
1903 #ifdef HAVE_WINDOW_SYSTEM
1904 if (FRAME_WINDOW_P (f
))
1905 return make_number (x_pixel_height (f
));
1908 return make_number (FRAME_HEIGHT (f
));
1911 DEFUN ("frame-pixel-width", Fframe_pixel_width
,
1912 Sframe_pixel_width
, 0, 1, 0,
1913 "Return FRAME's width in pixels.\n\
1914 For a terminal frame, the result really gives the width in characters.\n\
1915 If FRAME is omitted, the selected frame is used.")
1925 CHECK_FRAME (frame
, 0);
1929 #ifdef HAVE_WINDOW_SYSTEM
1930 if (FRAME_WINDOW_P (f
))
1931 return make_number (x_pixel_width (f
));
1934 return make_number (FRAME_WIDTH (f
));
1937 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 3, 0,
1938 "Specify that the frame FRAME has LINES lines.\n\
1939 Optional third arg non-nil means that redisplay should use LINES lines\n\
1940 but that the idea of the actual height of the frame should not be changed.")
1941 (frame
, lines
, pretend
)
1942 Lisp_Object frame
, lines
, pretend
;
1944 register struct frame
*f
;
1946 CHECK_NUMBER (lines
, 0);
1951 CHECK_LIVE_FRAME (frame
, 0);
1955 /* I think this should be done with a hook. */
1956 #ifdef HAVE_WINDOW_SYSTEM
1957 if (FRAME_WINDOW_P (f
))
1959 if (XINT (lines
) != f
->height
)
1960 x_set_window_size (f
, 1, f
->width
, XINT (lines
));
1964 change_frame_size (f
, XINT (lines
), 0, !NILP (pretend
), 0);
1968 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 3, 0,
1969 "Specify that the frame FRAME has COLS columns.\n\
1970 Optional third arg non-nil means that redisplay should use COLS columns\n\
1971 but that the idea of the actual width of the frame should not be changed.")
1972 (frame
, cols
, pretend
)
1973 Lisp_Object frame
, cols
, pretend
;
1975 register struct frame
*f
;
1976 CHECK_NUMBER (cols
, 0);
1981 CHECK_LIVE_FRAME (frame
, 0);
1985 /* I think this should be done with a hook. */
1986 #ifdef HAVE_WINDOW_SYSTEM
1987 if (FRAME_WINDOW_P (f
))
1989 if (XINT (cols
) != f
->width
)
1990 x_set_window_size (f
, 1, XINT (cols
), f
->height
);
1994 change_frame_size (f
, 0, XINT (cols
), !NILP (pretend
), 0);
1998 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 3, 0,
1999 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2001 Lisp_Object frame
, cols
, rows
;
2003 register struct frame
*f
;
2006 CHECK_LIVE_FRAME (frame
, 0);
2007 CHECK_NUMBER (cols
, 2);
2008 CHECK_NUMBER (rows
, 1);
2011 /* I think this should be done with a hook. */
2012 #ifdef HAVE_WINDOW_SYSTEM
2013 if (FRAME_WINDOW_P (f
))
2015 if (XINT (rows
) != f
->height
|| XINT (cols
) != f
->width
2016 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
2017 x_set_window_size (f
, 1, XINT (cols
), XINT (rows
));
2021 change_frame_size (f
, XINT (rows
), XINT (cols
), 0, 0);
2026 DEFUN ("set-frame-position", Fset_frame_position
,
2027 Sset_frame_position
, 3, 3, 0,
2028 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2029 This is actually the position of the upper left corner of the frame.\n\
2030 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2031 the rightmost or bottommost possible position (that stays within the screen).")
2032 (frame
, xoffset
, yoffset
)
2033 Lisp_Object frame
, xoffset
, yoffset
;
2035 register struct frame
*f
;
2038 CHECK_LIVE_FRAME (frame
, 0);
2039 CHECK_NUMBER (xoffset
, 1);
2040 CHECK_NUMBER (yoffset
, 2);
2043 /* I think this should be done with a hook. */
2044 #ifdef HAVE_WINDOW_SYSTEM
2045 if (FRAME_WINDOW_P (f
))
2046 x_set_offset (f
, XINT (xoffset
), XINT (yoffset
), 1);
2057 staticpro (&Vframe_list
);
2059 DEFVAR_LISP ("terminal-frame", &Vterminal_frame
,
2060 "The initial frame-object, which represents Emacs's stdout.");
2062 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified
,
2063 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2064 Vemacs_iconified
= Qnil
;
2066 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame
,
2067 "Minibufferless frames use this frame's minibuffer.\n\
2069 Emacs cannot create minibufferless frames unless this is set to an\n\
2070 appropriate surrogate.\n\
2072 Emacs consults this variable only when creating minibufferless\n\
2073 frames; once the frame is created, it sticks with its assigned\n\
2074 minibuffer, no matter what this variable is set to. This means that\n\
2075 this variable doesn't necessarily say anything meaningful about the\n\
2076 current set of frames, or where the minibuffer is currently being\n\
2079 defsubr (&Sactive_minibuffer_window
);
2081 defsubr (&Sframe_live_p
);
2082 defsubr (&Smake_terminal_frame
);
2083 defsubr (&Shandle_switch_frame
);
2084 defsubr (&Signore_event
);
2085 defsubr (&Sselect_frame
);
2086 defsubr (&Sselected_frame
);
2087 defsubr (&Swindow_frame
);
2088 defsubr (&Sframe_root_window
);
2089 defsubr (&Sframe_first_window
);
2090 defsubr (&Sframe_selected_window
);
2091 defsubr (&Sset_frame_selected_window
);
2092 defsubr (&Sframe_list
);
2093 defsubr (&Snext_frame
);
2094 defsubr (&Sprevious_frame
);
2095 defsubr (&Sdelete_frame
);
2096 defsubr (&Smouse_position
);
2097 defsubr (&Smouse_pixel_position
);
2098 defsubr (&Sset_mouse_position
);
2099 defsubr (&Sset_mouse_pixel_position
);
2101 defsubr (&Sframe_configuration
);
2102 defsubr (&Srestore_frame_configuration
);
2104 defsubr (&Smake_frame_visible
);
2105 defsubr (&Smake_frame_invisible
);
2106 defsubr (&Siconify_frame
);
2107 defsubr (&Sframe_visible_p
);
2108 defsubr (&Svisible_frame_list
);
2109 defsubr (&Sraise_frame
);
2110 defsubr (&Slower_frame
);
2111 defsubr (&Sredirect_frame_focus
);
2112 defsubr (&Sframe_focus
);
2113 defsubr (&Sframe_parameters
);
2114 defsubr (&Smodify_frame_parameters
);
2115 defsubr (&Sframe_char_height
);
2116 defsubr (&Sframe_char_width
);
2117 defsubr (&Sframe_pixel_height
);
2118 defsubr (&Sframe_pixel_width
);
2119 defsubr (&Sset_frame_height
);
2120 defsubr (&Sset_frame_width
);
2121 defsubr (&Sset_frame_size
);
2122 defsubr (&Sset_frame_position
);
2127 initial_define_lispy_key (global_map
, "switch-frame", "handle-switch-frame");
2128 initial_define_lispy_key (global_map
, "delete-frame", "handle-delete-frame");
2129 initial_define_lispy_key (global_map
, "iconify-frame", "ignore-event");
2130 initial_define_lispy_key (global_map
, "make-frame-visible", "ignore-event");