1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997 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 #ifdef HAVE_WINDOW_SYSTEM
30 #include "termhooks.h"
36 /* Evaluate this expression to rebuild the section of syms_of_frame
37 that initializes and staticpros the symbols declared below. Note
38 that Emacs 18 has a bug that keeps C-x C-e from being able to
39 evaluate this expression.
42 ;; Accumulate a list of the symbols we want to initialize from the
43 ;; declarations at the top of the file.
44 (goto-char (point-min))
45 (search-forward "/\*&&& symbols declared here &&&*\/\n")
47 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
49 (cons (buffer-substring (match-beginning 1) (match-end 1))
52 (setq symbol-list (nreverse symbol-list))
53 ;; Delete the section of syms_of_... where we initialize the symbols.
54 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
55 (let ((start (point)))
56 (while (looking-at "^ Q")
58 (kill-region start (point)))
59 ;; Write a new symbol initialization section.
61 (insert (format " %s = intern (\"" (car symbol-list)))
62 (let ((start (point)))
63 (insert (substring (car symbol-list) 1))
64 (subst-char-in-region start (point) ?_ ?-))
65 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
66 (setq symbol-list (cdr symbol-list)))))
69 /*&&& symbols declared here &&&*/
71 Lisp_Object Qframe_live_p
;
74 Lisp_Object Qminibuffer
;
75 Lisp_Object Qmodeline
;
78 Lisp_Object Qunsplittable
;
79 Lisp_Object Qmenu_bar_lines
;
85 Lisp_Object Qbuffer_predicate
;
86 Lisp_Object Qbuffer_list
;
89 Lisp_Object Vterminal_frame
;
90 Lisp_Object Vdefault_frame_alist
;
95 /*&&& init symbols here &&&*/
96 Qframep
= intern ("framep");
98 Qframe_live_p
= intern ("frame-live-p");
99 staticpro (&Qframe_live_p
);
100 Qheight
= intern ("height");
101 staticpro (&Qheight
);
102 Qicon
= intern ("icon");
104 Qminibuffer
= intern ("minibuffer");
105 staticpro (&Qminibuffer
);
106 Qmodeline
= intern ("modeline");
107 staticpro (&Qmodeline
);
108 Qname
= intern ("name");
110 Qonly
= intern ("only");
112 Qunsplittable
= intern ("unsplittable");
113 staticpro (&Qunsplittable
);
114 Qmenu_bar_lines
= intern ("menu-bar-lines");
115 staticpro (&Qmenu_bar_lines
);
116 Qwidth
= intern ("width");
120 Qw32
= intern ("w32");
124 Qvisible
= intern ("visible");
125 staticpro (&Qvisible
);
126 Qbuffer_predicate
= intern ("buffer-predicate");
127 staticpro (&Qbuffer_predicate
);
128 Qbuffer_list
= intern ("buffer-list");
129 staticpro (&Qbuffer_list
);
130 Qtitle
= intern ("title");
133 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist
,
134 "Alist of default values for frame creation.\n\
135 These may be set in your init file, like this:\n\
136 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
137 These override values given in window system configuration data,\n\
138 including X Windows' defaults database.\n\
139 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
140 For values specific to the separate minibuffer frame, see\n\
141 `minibuffer-frame-alist'.\n\
142 The `menu-bar-lines' element of the list controls whether new frames\n\
143 have menu bars; `menu-bar-mode' works by altering this element.");
144 Vdefault_frame_alist
= Qnil
;
148 set_menu_bar_lines_1 (window
, n
)
152 struct window
*w
= XWINDOW (window
);
154 XSETFASTINT (w
->last_modified
, 0);
155 XSETFASTINT (w
->top
, XFASTINT (w
->top
) + n
);
156 XSETFASTINT (w
->height
, XFASTINT (w
->height
) - n
);
158 /* Handle just the top child in a vertical split. */
159 if (!NILP (w
->vchild
))
160 set_menu_bar_lines_1 (w
->vchild
, n
);
162 /* Adjust all children in a horizontal split. */
163 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
165 w
= XWINDOW (window
);
166 set_menu_bar_lines_1 (window
, n
);
171 set_menu_bar_lines (f
, value
, oldval
)
173 Lisp_Object value
, oldval
;
176 int olines
= FRAME_MENU_BAR_LINES (f
);
178 /* Right now, menu bars don't work properly in minibuf-only frames;
179 most of the commands try to apply themselves to the minibuffer
180 frame itself, and get an error because you can't switch buffers
181 in or split the minibuffer window. */
182 if (FRAME_MINIBUF_ONLY_P (f
))
185 if (INTEGERP (value
))
186 nlines
= XINT (value
);
190 if (nlines
!= olines
)
192 windows_or_buffers_changed
++;
193 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
194 FRAME_MENU_BAR_LINES (f
) = nlines
;
195 set_menu_bar_lines_1 (f
->root_window
, nlines
- olines
);
201 /* These help us bind and responding to switch-frame events. */
202 #include "commands.h"
203 #include "keyboard.h"
205 Lisp_Object Vemacs_iconified
;
206 Lisp_Object Vframe_list
;
208 extern Lisp_Object Vminibuffer_list
;
209 extern Lisp_Object
get_minibuffer ();
210 extern Lisp_Object
Fhandle_switch_frame ();
211 extern Lisp_Object
Fredirect_frame_focus ();
212 extern Lisp_Object
x_get_focus_frame ();
214 DEFUN ("framep", Fframep
, Sframep
, 1, 1, 0,
215 "Return non-nil if OBJECT is a frame.\n\
216 Value is t for a termcap frame (a character-only terminal),\n\
217 `x' for an Emacs frame that is really an X window,\n\
218 `pc' for a direct-write MS-DOS frame.\n\
219 See also `frame-live-p'.")
223 if (!FRAMEP (object
))
225 switch (XFRAME (object
)->output_method
)
229 case output_x_window
:
233 case output_msdos_raw
:
240 DEFUN ("frame-live-p", Fframe_live_p
, Sframe_live_p
, 1, 1, 0,
241 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
242 Value is nil if OBJECT is not a live frame. If object is a live\n\
243 frame, the return value indicates what sort of output device it is\n\
244 displayed on. Value is t for a termcap frame (a character-only\n\
245 terminal), `x' for an Emacs frame being displayed in an X window.")
249 return ((FRAMEP (object
)
250 && FRAME_LIVE_P (XFRAME (object
)))
260 register struct frame
*f
;
261 register Lisp_Object root_window
;
262 register Lisp_Object mini_window
;
263 register struct Lisp_Vector
*vec
;
266 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct frame
));
267 for (i
= 0; i
< VECSIZE (struct frame
); i
++)
268 XSETFASTINT (vec
->contents
[i
], 0);
269 vec
->size
= VECSIZE (struct frame
);
270 f
= (struct frame
*)vec
;
271 XSETFRAME (frame
, f
);
275 f
->current_glyphs
= 0;
276 f
->desired_glyphs
= 0;
278 f
->async_visible
= 0;
279 f
->output_data
.nothing
= 0;
281 f
->async_iconified
= 0;
282 f
->wants_modeline
= 1;
287 f
->has_minibuffer
= mini_p
;
288 f
->focus_frame
= Qnil
;
289 f
->explicit_name
= 0;
290 f
->can_have_scroll_bars
= 0;
291 f
->vertical_scroll_bar_type
= vertical_scroll_bar_none
;
292 f
->param_alist
= Qnil
;
293 f
->scroll_bars
= Qnil
;
294 f
->condemned_scroll_bars
= Qnil
;
295 f
->face_alist
= Qnil
;
296 f
->menu_bar_items
= Qnil
;
297 f
->menu_bar_vector
= Qnil
;
298 f
->menu_bar_items_used
= 0;
299 f
->buffer_predicate
= Qnil
;
300 f
->buffer_list
= Qnil
;
302 f
->kboard
= initial_kboard
;
307 root_window
= make_window ();
310 mini_window
= make_window ();
311 XWINDOW (root_window
)->next
= mini_window
;
312 XWINDOW (mini_window
)->prev
= root_window
;
313 XWINDOW (mini_window
)->mini_p
= Qt
;
314 XWINDOW (mini_window
)->frame
= frame
;
315 f
->minibuffer_window
= mini_window
;
320 XWINDOW (root_window
)->next
= Qnil
;
321 f
->minibuffer_window
= Qnil
;
324 XWINDOW (root_window
)->frame
= frame
;
327 just so that there is "something there."
328 Correct size will be set up later with change_frame_size. */
330 SET_FRAME_WIDTH (f
, 10);
333 XSETFASTINT (XWINDOW (root_window
)->width
, 10);
334 XSETFASTINT (XWINDOW (root_window
)->height
, (mini_p
? 9 : 10));
338 XSETFASTINT (XWINDOW (mini_window
)->width
, 10);
339 XSETFASTINT (XWINDOW (mini_window
)->top
, 9);
340 XSETFASTINT (XWINDOW (mini_window
)->height
, 1);
343 /* Choose a buffer for the frame's root window. */
347 XWINDOW (root_window
)->buffer
= Qt
;
348 buf
= Fcurrent_buffer ();
349 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
350 a space), try to find another one. */
351 if (XSTRING (Fbuffer_name (buf
))->data
[0] == ' ')
352 buf
= Fother_buffer (buf
, Qnil
);
353 Fset_window_buffer (root_window
, buf
);
355 f
->buffer_list
= Fcons (buf
, Qnil
);
360 XWINDOW (mini_window
)->buffer
= Qt
;
361 Fset_window_buffer (mini_window
,
362 (NILP (Vminibuffer_list
)
364 : Fcar (Vminibuffer_list
)));
367 f
->root_window
= root_window
;
368 f
->selected_window
= root_window
;
369 /* Make sure this window seems more recently used than
370 a newly-created, never-selected window. */
371 XSETFASTINT (XWINDOW (f
->selected_window
)->use_time
, ++window_select_count
);
373 #ifdef HAVE_WINDOW_SYSTEM
374 f
->fontset_data
= alloc_fontset_data ();
380 /* Make a frame using a separate minibuffer window on another frame.
381 MINI_WINDOW is the minibuffer window to use. nil means use the
382 default (the global minibuffer). */
385 make_frame_without_minibuffer (mini_window
, kb
, display
)
386 register Lisp_Object mini_window
;
390 register struct frame
*f
;
393 if (!NILP (mini_window
))
394 CHECK_LIVE_WINDOW (mini_window
, 0);
397 if (!NILP (mini_window
)
398 && XFRAME (XWINDOW (mini_window
)->frame
)->kboard
!= kb
)
399 error ("frame and minibuffer must be on the same display");
402 /* Make a frame containing just a root window. */
405 if (NILP (mini_window
))
407 /* Use default-minibuffer-frame if possible. */
408 if (!FRAMEP (kb
->Vdefault_minibuffer_frame
)
409 || ! FRAME_LIVE_P (XFRAME (kb
->Vdefault_minibuffer_frame
)))
411 Lisp_Object frame_dummy
;
413 XSETFRAME (frame_dummy
, f
);
414 GCPRO1 (frame_dummy
);
415 /* If there's no minibuffer frame to use, create one. */
416 kb
->Vdefault_minibuffer_frame
=
417 call1 (intern ("make-initial-minibuffer-frame"), display
);
421 mini_window
= XFRAME (kb
->Vdefault_minibuffer_frame
)->minibuffer_window
;
424 f
->minibuffer_window
= mini_window
;
426 /* Make the chosen minibuffer window display the proper minibuffer,
427 unless it is already showing a minibuffer. */
428 if (NILP (Fmemq (XWINDOW (mini_window
)->buffer
, Vminibuffer_list
)))
429 Fset_window_buffer (mini_window
,
430 (NILP (Vminibuffer_list
)
432 : Fcar (Vminibuffer_list
)));
436 /* Make a frame containing only a minibuffer window. */
439 make_minibuffer_frame ()
441 /* First make a frame containing just a root window, no minibuffer. */
443 register struct frame
*f
= make_frame (0);
444 register Lisp_Object mini_window
;
445 register Lisp_Object frame
;
447 XSETFRAME (frame
, f
);
452 f
->wants_modeline
= 0;
453 f
->has_minibuffer
= 1;
455 /* Now label the root window as also being the minibuffer.
456 Avoid infinite looping on the window chain by marking next pointer
459 mini_window
= f
->minibuffer_window
= f
->root_window
;
460 XWINDOW (mini_window
)->mini_p
= Qt
;
461 XWINDOW (mini_window
)->next
= Qnil
;
462 XWINDOW (mini_window
)->prev
= Qnil
;
463 XWINDOW (mini_window
)->frame
= frame
;
465 /* Put the proper buffer in that window. */
467 Fset_window_buffer (mini_window
,
468 (NILP (Vminibuffer_list
)
470 : Fcar (Vminibuffer_list
)));
474 /* Construct a frame that refers to the terminal (stdin and stdout). */
476 static int terminal_frame_count
;
479 make_terminal_frame ()
481 register struct frame
*f
;
488 initial_kboard
= (KBOARD
*) xmalloc (sizeof (KBOARD
));
489 init_kboard (initial_kboard
);
490 initial_kboard
->next_kboard
= all_kboards
;
491 all_kboards
= initial_kboard
;
495 /* The first call must initialize Vframe_list. */
496 if (! (NILP (Vframe_list
) || CONSP (Vframe_list
)))
501 XSETFRAME (frame
, f
);
502 Vframe_list
= Fcons (frame
, Vframe_list
);
504 terminal_frame_count
++;
505 if (terminal_frame_count
== 1)
507 f
->name
= build_string ("Emacs");
511 sprintf (name
, "Emacs-%d", terminal_frame_count
);
512 f
->name
= build_string (name
);
515 f
->visible
= 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
516 f
->async_visible
= 1; /* Don't let visible be cleared later. */
518 f
->output_data
.x
= &the_only_x_display
;
519 f
->output_method
= output_msdos_raw
;
520 init_frame_faces (f
);
521 #else /* not MSDOS */
522 f
->output_data
.nothing
= 1; /* Nonzero means frame isn't deleted. */
527 DEFUN ("make-terminal-frame", Fmake_terminal_frame
, Smake_terminal_frame
,
528 1, 1, 0, "Create an additional terminal frame.\n\
529 You can create multiple frames on a text-only terminal in this way.\n\
530 Only the selected terminal frame is actually displayed.\n\
531 This function takes one argument, an alist specifying frame parameters.\n\
532 In practice, generally you don't need to specify any parameters.\n\
533 Note that changing the size of one terminal frame automatically affects all.")
541 if (selected_frame
->output_method
!= output_msdos_raw
)
544 if (selected_frame
->output_method
!= output_termcap
)
545 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
548 f
= make_terminal_frame ();
549 change_frame_size (f
, FRAME_HEIGHT (selected_frame
),
550 FRAME_WIDTH (selected_frame
), 0, 0);
551 remake_frame_glyphs (f
);
553 XSETFRAME (frame
, f
);
554 Fmodify_frame_parameters (frame
, Vdefault_frame_alist
);
555 Fmodify_frame_parameters (frame
, parms
);
556 f
->face_alist
= selected_frame
->face_alist
;
561 do_switch_frame (frame
, no_enter
, track
)
562 Lisp_Object frame
, no_enter
;
565 /* If FRAME is a switch-frame event, extract the frame we should
568 && EQ (XCONS (frame
)->car
, Qswitch_frame
)
569 && CONSP (XCONS (frame
)->cdr
))
570 frame
= XCONS (XCONS (frame
)->cdr
)->car
;
572 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
573 a switch-frame event to arrive after a frame is no longer live,
574 especially when deleting the initial frame during startup. */
575 CHECK_FRAME (frame
, 0);
576 if (! FRAME_LIVE_P (XFRAME (frame
)))
579 if (selected_frame
== XFRAME (frame
))
582 /* This is too greedy; it causes inappropriate focus redirection
583 that's hard to get rid of. */
585 /* If a frame's focus has been redirected toward the currently
586 selected frame, we should change the redirection to point to the
587 newly selected frame. This means that if the focus is redirected
588 from a minibufferless frame to a surrogate minibuffer frame, we
589 can use `other-window' to switch between all the frames using
590 that minibuffer frame, and the focus redirection will follow us
596 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
600 if (!FRAMEP (XCONS (tail
)->car
))
603 focus
= FRAME_FOCUS_FRAME (XFRAME (XCONS (tail
)->car
));
605 if (FRAMEP (focus
) && XFRAME (focus
) == selected_frame
)
606 Fredirect_frame_focus (XCONS (tail
)->car
, frame
);
610 /* Instead, apply it only to the frame we're pointing to. */
611 #ifdef HAVE_WINDOW_SYSTEM
612 if (track
&& (FRAME_WINDOW_P (XFRAME (frame
))))
614 Lisp_Object focus
, xfocus
;
616 xfocus
= x_get_focus_frame (XFRAME (frame
));
619 focus
= FRAME_FOCUS_FRAME (XFRAME (xfocus
));
620 if (FRAMEP (focus
) && XFRAME (focus
) == selected_frame
)
621 Fredirect_frame_focus (xfocus
, frame
);
624 #endif /* HAVE_X_WINDOWS */
627 selected_frame
= XFRAME (frame
);
628 if (! FRAME_MINIBUF_ONLY_P (selected_frame
))
629 last_nonminibuf_frame
= selected_frame
;
631 Fselect_window (XFRAME (frame
)->selected_window
);
633 /* We want to make sure that the next event generates a frame-switch
634 event to the appropriate frame. This seems kludgy to me, but
635 before you take it out, make sure that evaluating something like
636 (select-window (frame-root-window (new-frame))) doesn't end up
637 with your typing being interpreted in the new frame instead of
638 the one you're actually typing in. */
639 internal_last_event_frame
= Qnil
;
644 DEFUN ("select-frame", Fselect_frame
, Sselect_frame
, 1, 2, "e",
645 "Select the frame FRAME.\n\
646 Subsequent editing commands apply to its selected window.\n\
647 The selection of FRAME lasts until the next time the user does\n\
648 something to select a different frame, or until the next time this\n\
649 function is called.")
651 Lisp_Object frame
, no_enter
;
653 return do_switch_frame (frame
, no_enter
, 1);
657 DEFUN ("handle-switch-frame", Fhandle_switch_frame
, Shandle_switch_frame
, 1, 2, "e",
658 "Handle a switch-frame event EVENT.\n\
659 Switch-frame events are usually bound to this function.\n\
660 A switch-frame event tells Emacs that the window manager has requested\n\
661 that the user's events be directed to the frame mentioned in the event.\n\
662 This function selects the selected window of the frame of EVENT.\n\
664 If EVENT is frame object, handle it as if it were a switch-frame event\n\
667 Lisp_Object event
, no_enter
;
669 /* Preserve prefix arg that the command loop just cleared. */
670 current_kboard
->Vprefix_arg
= Vcurrent_prefix_arg
;
671 call1 (Vrun_hooks
, Qmouse_leave_buffer_hook
);
672 return do_switch_frame (event
, no_enter
, 0);
675 DEFUN ("ignore-event", Fignore_event
, Signore_event
, 0, 0, "",
676 "Do nothing, but preserve any prefix argument already specified.\n\
677 This is a suitable binding for iconify-frame and make-frame-visible.")
680 current_kboard
->Vprefix_arg
= Vcurrent_prefix_arg
;
684 DEFUN ("selected-frame", Fselected_frame
, Sselected_frame
, 0, 0, 0,
685 "Return the frame that is now selected.")
689 XSETFRAME (tem
, selected_frame
);
693 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 1, 1, 0,
694 "Return the frame object that window WINDOW is on.")
698 CHECK_LIVE_WINDOW (window
, 0);
699 return XWINDOW (window
)->frame
;
702 DEFUN ("frame-first-window", Fframe_first_window
, Sframe_first_window
, 0, 1, 0,
703 "Returns the topmost, leftmost window of FRAME.\n\
704 If omitted, FRAME defaults to the currently selected frame.")
711 w
= selected_frame
->root_window
;
714 CHECK_LIVE_FRAME (frame
, 0);
715 w
= XFRAME (frame
)->root_window
;
717 while (NILP (XWINDOW (w
)->buffer
))
719 if (! NILP (XWINDOW (w
)->hchild
))
720 w
= XWINDOW (w
)->hchild
;
721 else if (! NILP (XWINDOW (w
)->vchild
))
722 w
= XWINDOW (w
)->vchild
;
729 DEFUN ("active-minibuffer-window", Factive_minibuffer_window
,
730 Sactive_minibuffer_window
, 0, 0, 0,
731 "Return the currently active minibuffer window, or nil if none.")
734 return minibuf_level
? minibuf_window
: Qnil
;
737 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
738 "Returns the root-window of 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
)->root_window
;
751 DEFUN ("frame-selected-window", Fframe_selected_window
,
752 Sframe_selected_window
, 0, 1, 0,
753 "Return the selected window of frame object FRAME.\n\
754 If omitted, FRAME defaults to the currently selected frame.")
759 XSETFRAME (frame
, selected_frame
);
761 CHECK_LIVE_FRAME (frame
, 0);
763 return XFRAME (frame
)->selected_window
;
766 DEFUN ("set-frame-selected-window", Fset_frame_selected_window
,
767 Sset_frame_selected_window
, 2, 2, 0,
768 "Set the selected window of frame object FRAME to WINDOW.\n\
769 If FRAME is nil, the selected frame is used.\n\
770 If FRAME is the selected frame, this makes WINDOW the selected window.")
772 Lisp_Object frame
, window
;
775 XSETFRAME (frame
, selected_frame
);
777 CHECK_LIVE_FRAME (frame
, 0);
779 CHECK_LIVE_WINDOW (window
, 1);
781 if (! EQ (frame
, WINDOW_FRAME (XWINDOW (window
))))
782 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
784 if (XFRAME (frame
) == selected_frame
)
785 return Fselect_window (window
);
787 return XFRAME (frame
)->selected_window
= window
;
790 DEFUN ("frame-list", Fframe_list
, Sframe_list
,
792 "Return a list of all frames.")
795 return Fcopy_sequence (Vframe_list
);
798 /* Return the next frame in the frame list after FRAME.
799 If MINIBUF is nil, exclude minibuffer-only frames.
800 If MINIBUF is a window, include only its own frame
801 and any frame now using that window as the minibuffer.
802 If MINIBUF is `visible', include all visible frames.
803 If MINIBUF is 0, include all visible and iconified frames.
804 Otherwise, include all frames. */
807 next_frame (frame
, minibuf
)
814 /* There must always be at least one frame in Vframe_list. */
815 if (! CONSP (Vframe_list
))
818 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
819 forever. Forestall that. */
820 CHECK_LIVE_FRAME (frame
, 0);
823 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
827 f
= XCONS (tail
)->car
;
830 && FRAME_KBOARD (XFRAME (f
)) == FRAME_KBOARD (XFRAME (frame
)))
832 /* Decide whether this frame is eligible to be returned. */
834 /* If we've looped all the way around without finding any
835 eligible frames, return the original frame. */
839 /* Let minibuf decide if this frame is acceptable. */
842 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
845 else if (EQ (minibuf
, Qvisible
))
847 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
848 if (FRAME_VISIBLE_P (XFRAME (f
)))
851 else if (XFASTINT (minibuf
) == 0)
853 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
854 if (FRAME_VISIBLE_P (XFRAME (f
))
855 || FRAME_ICONIFIED_P (XFRAME (f
)))
858 else if (WINDOWP (minibuf
))
860 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
)
861 /* Check that F either is, or has forwarded its focus to,
863 && (EQ (WINDOW_FRAME (XWINDOW (minibuf
)), f
)
864 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
865 FRAME_FOCUS_FRAME (XFRAME (f
)))))
877 /* Return the previous frame in the frame list before FRAME.
878 If MINIBUF is nil, exclude minibuffer-only frames.
879 If MINIBUF is a window, include only its own frame
880 and any frame now using that window as the minibuffer.
881 If MINIBUF is `visible', include all visible frames.
882 If MINIBUF is 0, include all visible and iconified frames.
883 Otherwise, include all frames. */
886 prev_frame (frame
, minibuf
)
893 /* There must always be at least one frame in Vframe_list. */
894 if (! CONSP (Vframe_list
))
898 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
902 f
= XCONS (tail
)->car
;
906 if (EQ (frame
, f
) && !NILP (prev
))
909 if (FRAME_KBOARD (XFRAME (f
)) == FRAME_KBOARD (XFRAME (frame
)))
911 /* Decide whether this frame is eligible to be returned,
912 according to minibuf. */
915 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f
)))
918 else if (WINDOWP (minibuf
))
920 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f
)), minibuf
)
921 /* Check that F either is, or has forwarded its focus to,
923 && (EQ (WINDOW_FRAME (XWINDOW (minibuf
)), f
)
924 || EQ (WINDOW_FRAME (XWINDOW (minibuf
)),
925 FRAME_FOCUS_FRAME (XFRAME (f
)))))
928 else if (EQ (minibuf
, Qvisible
))
930 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
931 if (FRAME_VISIBLE_P (XFRAME (f
)))
934 else if (XFASTINT (minibuf
) == 0)
936 FRAME_SAMPLE_VISIBILITY (XFRAME (f
));
937 if (FRAME_VISIBLE_P (XFRAME (f
))
938 || FRAME_ICONIFIED_P (XFRAME (f
)))
946 /* We've scanned the entire list. */
948 /* We went through the whole frame list without finding a single
949 acceptable frame. Return the original frame. */
952 /* There were no acceptable frames in the list before FRAME; otherwise,
953 we would have returned directly from the loop. Since PREV is the last
954 acceptable frame in the list, return it. */
959 DEFUN ("next-frame", Fnext_frame
, Snext_frame
, 0, 2, 0,
960 "Return the next frame in the frame list after FRAME.\n\
961 It considers only frames on the same terminal as FRAME.\n\
962 By default, skip minibuffer-only frames.\n\
963 If omitted, FRAME defaults to the selected frame.\n\
964 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
965 If MINIFRAME is a window, include only its own frame\n\
966 and any frame now using that window as the minibuffer.\n\
967 If MINIFRAME is `visible', include all visible frames.\n\
968 If MINIFRAME is 0, include all visible and iconified frames.\n\
969 Otherwise, include all frames.")
971 Lisp_Object frame
, miniframe
;
976 XSETFRAME (frame
, selected_frame
);
978 CHECK_LIVE_FRAME (frame
, 0);
980 return next_frame (frame
, miniframe
);
983 DEFUN ("previous-frame", Fprevious_frame
, Sprevious_frame
, 0, 2, 0,
984 "Return the previous frame in the frame list before FRAME.\n\
985 It considers only frames on the same terminal as FRAME.\n\
986 By default, skip minibuffer-only frames.\n\
987 If omitted, FRAME defaults to the selected frame.\n\
988 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
989 If MINIFRAME is a window, include only its own frame\n\
990 and any frame now using that window as the minibuffer.\n\
991 If MINIFRAME is `visible', include all visible frames.\n\
992 If MINIFRAME is 0, include all visible and iconified frames.\n\
993 Otherwise, include all frames.")
995 Lisp_Object frame
, miniframe
;
1000 XSETFRAME (frame
, selected_frame
);
1002 CHECK_LIVE_FRAME (frame
, 0);
1004 return prev_frame (frame
, miniframe
);
1007 /* Return 1 if it is ok to delete frame F;
1008 0 if all frames aside from F are invisible.
1009 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1012 other_visible_frames (f
)
1015 /* We know the selected frame is visible,
1016 so if F is some other frame, it can't be the sole visible one. */
1017 if (f
== selected_frame
)
1022 for (frames
= Vframe_list
;
1024 frames
= XCONS (frames
)->cdr
)
1028 this = XCONS (frames
)->car
;
1029 /* Verify that the frame's window still exists
1030 and we can still talk to it. And note any recent change
1032 #ifdef HAVE_WINDOW_SYSTEM
1033 if (FRAME_WINDOW_P (XFRAME (this)))
1035 x_sync (XFRAME (this));
1036 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1040 if (FRAME_VISIBLE_P (XFRAME (this))
1041 || FRAME_ICONIFIED_P (XFRAME (this))
1042 /* Allow deleting the terminal frame when at least
1043 one X frame exists! */
1044 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f
)))
1052 DEFUN ("delete-frame", Fdelete_frame
, Sdelete_frame
, 0, 2, "",
1053 "Delete FRAME, permanently eliminating it from use.\n\
1054 If omitted, FRAME defaults to the selected frame.\n\
1055 A frame may not be deleted if its minibuffer is used by other frames.\n\
1056 Normally, you may not delete a frame if all other frames are invisible,\n\
1057 but if the second optional argument FORCE is non-nil, you may do so.")
1059 Lisp_Object frame
, force
;
1062 int minibuffer_selected
;
1064 if (EQ (frame
, Qnil
))
1067 XSETFRAME (frame
, f
);
1071 CHECK_FRAME (frame
, 0);
1075 if (! FRAME_LIVE_P (f
))
1078 if (NILP (force
) && !other_visible_frames (f
))
1079 error ("Attempt to delete the sole visible or iconified frame");
1081 /* Does this frame have a minibuffer, and is it the surrogate
1082 minibuffer for any other frame? */
1083 if (FRAME_HAS_MINIBUF_P (XFRAME (frame
)))
1087 for (frames
= Vframe_list
;
1089 frames
= XCONS (frames
)->cdr
)
1092 this = XCONS (frames
)->car
;
1094 if (! EQ (this, frame
)
1096 WINDOW_FRAME (XWINDOW
1097 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1098 error ("Attempt to delete a surrogate minibuffer frame");
1102 minibuffer_selected
= EQ (minibuf_window
, selected_window
);
1104 /* Don't let the frame remain selected. */
1105 if (f
== selected_frame
)
1107 Lisp_Object tail
, frame1
;
1109 /* Look for another visible frame on the same terminal. */
1110 frame1
= next_frame (frame
, Qvisible
);
1112 /* If there is none, find *some* other frame. */
1113 if (NILP (frame1
) || EQ (frame1
, frame
))
1115 FOR_EACH_FRAME (tail
, frame1
)
1117 if (! EQ (frame
, frame1
))
1122 do_switch_frame (frame1
, Qnil
, 0);
1125 /* Don't allow minibuf_window to remain on a deleted frame. */
1126 if (EQ (f
->minibuffer_window
, minibuf_window
))
1128 Fset_window_buffer (selected_frame
->minibuffer_window
,
1129 XWINDOW (minibuf_window
)->buffer
);
1130 minibuf_window
= selected_frame
->minibuffer_window
;
1132 /* If the dying minibuffer window was selected,
1133 select the new one. */
1134 if (minibuffer_selected
)
1135 Fselect_window (minibuf_window
);
1138 /* Clear any X selections for this frame. */
1139 #ifdef HAVE_X_WINDOWS
1141 x_clear_frame_selections (f
);
1144 /* Mark all the windows that used to be on FRAME as deleted, and then
1145 remove the reference to them. */
1146 delete_all_subwindows (XWINDOW (f
->root_window
));
1147 f
->root_window
= Qnil
;
1149 Vframe_list
= Fdelq (frame
, Vframe_list
);
1150 FRAME_SET_VISIBLE (f
, 0);
1154 if (FRAME_CURRENT_GLYPHS (f
))
1155 free_frame_glyphs (f
, FRAME_CURRENT_GLYPHS (f
));
1156 if (FRAME_DESIRED_GLYPHS (f
))
1157 free_frame_glyphs (f
, FRAME_DESIRED_GLYPHS (f
));
1158 if (FRAME_TEMP_GLYPHS (f
))
1159 free_frame_glyphs (f
, FRAME_TEMP_GLYPHS (f
));
1160 if (FRAME_INSERT_COST (f
))
1161 free (FRAME_INSERT_COST (f
));
1162 if (FRAME_DELETEN_COST (f
))
1163 free (FRAME_DELETEN_COST (f
));
1164 if (FRAME_INSERTN_COST (f
))
1165 free (FRAME_INSERTN_COST (f
));
1166 if (FRAME_DELETE_COST (f
))
1167 free (FRAME_DELETE_COST (f
));
1169 #ifdef HAVE_WINDOW_SYSTEM
1170 /* Free all fontset data. */
1171 free_fontset_data (FRAME_FONTSET_DATA (f
));
1174 /* Since some events are handled at the interrupt level, we may get
1175 an event for f at any time; if we zero out the frame's display
1176 now, then we may trip up the event-handling code. Instead, we'll
1177 promise that the display of the frame must be valid until we have
1178 called the window-system-dependent frame destruction routine. */
1180 /* I think this should be done with a hook. */
1181 #ifdef HAVE_WINDOW_SYSTEM
1182 if (FRAME_WINDOW_P (f
))
1183 x_destroy_window (f
);
1186 f
->output_data
.nothing
= 0;
1188 /* If we've deleted the last_nonminibuf_frame, then try to find
1190 if (f
== last_nonminibuf_frame
)
1194 last_nonminibuf_frame
= 0;
1196 for (frames
= Vframe_list
;
1198 frames
= XCONS (frames
)->cdr
)
1200 f
= XFRAME (XCONS (frames
)->car
);
1201 if (!FRAME_MINIBUF_ONLY_P (f
))
1203 last_nonminibuf_frame
= f
;
1209 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1210 find another one. Prefer minibuffer-only frames, but also notice
1211 frames with other windows. */
1212 if (EQ (frame
, FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
))
1216 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1217 Lisp_Object frame_with_minibuf
;
1218 /* Some frame we found on the same kboard, or nil if there are none. */
1219 Lisp_Object frame_on_same_kboard
;
1221 frame_on_same_kboard
= Qnil
;
1222 frame_with_minibuf
= Qnil
;
1224 for (frames
= Vframe_list
;
1226 frames
= XCONS (frames
)->cdr
)
1231 this = XCONS (frames
)->car
;
1236 /* Consider only frames on the same kboard
1237 and only those with minibuffers. */
1238 if (FRAME_KBOARD (f
) == FRAME_KBOARD (f1
)
1239 && FRAME_HAS_MINIBUF_P (f1
))
1241 frame_with_minibuf
= this;
1242 if (FRAME_MINIBUF_ONLY_P (f1
))
1246 if (FRAME_KBOARD (f
) == FRAME_KBOARD (f1
))
1247 frame_on_same_kboard
= this;
1250 if (!NILP (frame_on_same_kboard
))
1252 /* We know that there must be some frame with a minibuffer out
1253 there. If this were not true, all of the frames present
1254 would have to be minibufferless, which implies that at some
1255 point their minibuffer frames must have been deleted, but
1256 that is prohibited at the top; you can't delete surrogate
1257 minibuffer frames. */
1258 if (NILP (frame_with_minibuf
))
1261 FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
= frame_with_minibuf
;
1264 /* No frames left on this kboard--say no minibuffer either. */
1265 FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
= Qnil
;
1268 /* Cause frame titles to update--necessary if we now have just one frame. */
1269 update_mode_lines
= 1;
1274 /* Return mouse position in character cell units. */
1276 DEFUN ("mouse-position", Fmouse_position
, Smouse_position
, 0, 0, 0,
1277 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1278 The position is given in character cells, where (0, 0) is the\n\
1279 upper-left corner.\n\
1280 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1281 to read the mouse position, it returns the selected frame for FRAME\n\
1282 and nil for X and Y.")
1286 Lisp_Object lispy_dummy
;
1287 enum scroll_bar_part party_dummy
;
1290 unsigned long long_dummy
;
1296 /* It's okay for the hook to refrain from storing anything. */
1297 if (mouse_position_hook
)
1298 (*mouse_position_hook
) (&f
, 0,
1299 &lispy_dummy
, &party_dummy
,
1306 pixel_to_glyph_coords (f
, col
, row
, &col
, &row
, NULL
, 1);
1311 XSETFRAME (lispy_dummy
, f
);
1312 return Fcons (lispy_dummy
, Fcons (x
, y
));
1315 DEFUN ("mouse-pixel-position", Fmouse_pixel_position
,
1316 Smouse_pixel_position
, 0, 0, 0,
1317 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1318 The position is given in pixel units, where (0, 0) is the\n\
1319 upper-left corner.\n\
1320 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1321 to read the mouse position, it returns the selected frame for FRAME\n\
1322 and nil for X and Y.")
1326 Lisp_Object lispy_dummy
;
1327 enum scroll_bar_part party_dummy
;
1330 unsigned long long_dummy
;
1336 /* It's okay for the hook to refrain from storing anything. */
1337 if (mouse_position_hook
)
1338 (*mouse_position_hook
) (&f
, 0,
1339 &lispy_dummy
, &party_dummy
,
1343 XSETFRAME (lispy_dummy
, f
);
1344 return Fcons (lispy_dummy
, Fcons (x
, y
));
1347 DEFUN ("set-mouse-position", Fset_mouse_position
, Sset_mouse_position
, 3, 3, 0,
1348 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1349 Note, this is a no-op for an X frame that is not visible.\n\
1350 If you have just created a frame, you must wait for it to become visible\n\
1351 before calling this function on it, like this.\n\
1352 (while (not (frame-visible-p frame)) (sleep-for .5))")
1354 Lisp_Object frame
, x
, y
;
1356 CHECK_LIVE_FRAME (frame
, 0);
1357 CHECK_NUMBER (x
, 2);
1358 CHECK_NUMBER (y
, 1);
1360 /* I think this should be done with a hook. */
1361 #ifdef HAVE_WINDOW_SYSTEM
1362 if (FRAME_WINDOW_P (XFRAME (frame
)))
1363 /* Warping the mouse will cause enternotify and focus events. */
1364 x_set_mouse_position (XFRAME (frame
), x
, y
);
1366 #if defined (MSDOS) && defined (HAVE_MOUSE)
1367 if (FRAME_MSDOS_P (XFRAME (frame
)))
1369 Fselect_frame (frame
, Qnil
);
1370 mouse_moveto (XINT (x
), XINT (y
));
1378 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position
,
1379 Sset_mouse_pixel_position
, 3, 3, 0,
1380 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1381 Note, this is a no-op for an X frame that is not visible.\n\
1382 If you have just created a frame, you must wait for it to become visible\n\
1383 before calling this function on it, like this.\n\
1384 (while (not (frame-visible-p frame)) (sleep-for .5))")
1386 Lisp_Object frame
, x
, y
;
1388 CHECK_LIVE_FRAME (frame
, 0);
1389 CHECK_NUMBER (x
, 2);
1390 CHECK_NUMBER (y
, 1);
1392 /* I think this should be done with a hook. */
1393 #ifdef HAVE_WINDOW_SYSTEM
1394 if (FRAME_WINDOW_P (XFRAME (frame
)))
1395 /* Warping the mouse will cause enternotify and focus events. */
1396 x_set_mouse_pixel_position (XFRAME (frame
), x
, y
);
1398 #if defined (MSDOS) && defined (HAVE_MOUSE)
1399 if (FRAME_MSDOS_P (XFRAME (frame
)))
1401 Fselect_frame (frame
, Qnil
);
1402 mouse_moveto (XINT (x
), XINT (y
));
1410 DEFUN ("make-frame-visible", Fmake_frame_visible
, Smake_frame_visible
,
1412 "Make the frame FRAME visible (assuming it is an X-window).\n\
1413 If omitted, FRAME defaults to the currently selected frame.")
1418 XSETFRAME (frame
, selected_frame
);
1420 CHECK_LIVE_FRAME (frame
, 0);
1422 /* I think this should be done with a hook. */
1423 #ifdef HAVE_WINDOW_SYSTEM
1424 if (FRAME_WINDOW_P (XFRAME (frame
)))
1426 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
1427 x_make_frame_visible (XFRAME (frame
));
1431 /* Make menu bar update for the Buffers and Frams menus. */
1432 windows_or_buffers_changed
++;
1437 DEFUN ("make-frame-invisible", Fmake_frame_invisible
, Smake_frame_invisible
,
1439 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1440 If omitted, FRAME defaults to the currently selected frame.\n\
1441 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1442 but if the second optional argument FORCE is non-nil, you may do so.")
1444 Lisp_Object frame
, force
;
1447 XSETFRAME (frame
, selected_frame
);
1449 CHECK_LIVE_FRAME (frame
, 0);
1451 if (NILP (force
) && !other_visible_frames (XFRAME (frame
)))
1452 error ("Attempt to make invisible the sole visible or iconified frame");
1454 #if 0 /* This isn't logically necessary, and it can do GC. */
1455 /* Don't let the frame remain selected. */
1456 if (XFRAME (frame
) == selected_frame
)
1457 do_switch_frame (next_frame (frame
, Qt
), Qnil
, 0)
1460 /* Don't allow minibuf_window to remain on a deleted frame. */
1461 if (EQ (XFRAME (frame
)->minibuffer_window
, minibuf_window
))
1463 Fset_window_buffer (selected_frame
->minibuffer_window
,
1464 XWINDOW (minibuf_window
)->buffer
);
1465 minibuf_window
= selected_frame
->minibuffer_window
;
1468 /* I think this should be done with a hook. */
1469 #ifdef HAVE_WINDOW_SYSTEM
1470 if (FRAME_WINDOW_P (XFRAME (frame
)))
1471 x_make_frame_invisible (XFRAME (frame
));
1474 /* Make menu bar update for the Buffers and Frams menus. */
1475 windows_or_buffers_changed
++;
1480 DEFUN ("iconify-frame", Ficonify_frame
, Siconify_frame
,
1482 "Make the frame FRAME into an icon.\n\
1483 If omitted, FRAME defaults to the currently selected frame.")
1488 XSETFRAME (frame
, selected_frame
);
1490 CHECK_LIVE_FRAME (frame
, 0);
1492 #if 0 /* This isn't logically necessary, and it can do GC. */
1493 /* Don't let the frame remain selected. */
1494 if (XFRAME (frame
) == selected_frame
)
1495 Fhandle_switch_frame (next_frame (frame
, Qt
), Qnil
);
1498 /* Don't allow minibuf_window to remain on a deleted frame. */
1499 if (EQ (XFRAME (frame
)->minibuffer_window
, minibuf_window
))
1501 Fset_window_buffer (selected_frame
->minibuffer_window
,
1502 XWINDOW (minibuf_window
)->buffer
);
1503 minibuf_window
= selected_frame
->minibuffer_window
;
1506 /* I think this should be done with a hook. */
1507 #ifdef HAVE_WINDOW_SYSTEM
1508 if (FRAME_WINDOW_P (XFRAME (frame
)))
1509 x_iconify_frame (XFRAME (frame
));
1512 /* Make menu bar update for the Buffers and Frams menus. */
1513 windows_or_buffers_changed
++;
1518 DEFUN ("frame-visible-p", Fframe_visible_p
, Sframe_visible_p
,
1520 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1521 A frame that is not \"visible\" is not updated and, if it works through\n\
1522 a window system, it may not show at all.\n\
1523 Return the symbol `icon' if frame is visible only as an icon.")
1527 CHECK_LIVE_FRAME (frame
, 0);
1529 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
1531 if (FRAME_VISIBLE_P (XFRAME (frame
)))
1533 if (FRAME_ICONIFIED_P (XFRAME (frame
)))
1538 DEFUN ("visible-frame-list", Fvisible_frame_list
, Svisible_frame_list
,
1540 "Return a list of all frames now \"visible\" (being updated).")
1543 Lisp_Object tail
, frame
;
1548 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1550 frame
= XCONS (tail
)->car
;
1551 if (!FRAMEP (frame
))
1554 if (FRAME_VISIBLE_P (f
))
1555 value
= Fcons (frame
, value
);
1561 DEFUN ("raise-frame", Fraise_frame
, Sraise_frame
, 0, 1, "",
1562 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1563 If FRAME is invisible, make it visible.\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 /* Do like the documentation says. */
1576 Fmake_frame_visible (frame
);
1578 if (frame_raise_lower_hook
)
1579 (*frame_raise_lower_hook
) (XFRAME (frame
), 1);
1584 /* Should we have a corresponding function called Flower_Power? */
1585 DEFUN ("lower-frame", Flower_frame
, Slower_frame
, 0, 1, "",
1586 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1587 If you don't specify a frame, the selected frame is used.\n\
1588 If Emacs is displaying on an ordinary terminal or some other device which\n\
1589 doesn't support multiple overlapping frames, this function does nothing.")
1594 XSETFRAME (frame
, selected_frame
);
1596 CHECK_LIVE_FRAME (frame
, 0);
1598 if (frame_raise_lower_hook
)
1599 (*frame_raise_lower_hook
) (XFRAME (frame
), 0);
1605 DEFUN ("redirect-frame-focus", Fredirect_frame_focus
, Sredirect_frame_focus
,
1607 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1608 In other words, switch-frame events caused by events in FRAME will\n\
1609 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1610 FOCUS-FRAME after reading an event typed at FRAME.\n\
1612 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1613 cancelled, and the frame again receives its own keystrokes.\n\
1615 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1616 a surrogate minibuffer frame when a frame doesn't have its own\n\
1617 minibuffer window.\n\
1619 A frame's focus redirection can be changed by select-frame. If frame\n\
1620 FOO is selected, and then a different frame BAR is selected, any\n\
1621 frames redirecting their focus to FOO are shifted to redirect their\n\
1622 focus to BAR. This allows focus redirection to work properly when the\n\
1623 user switches from one frame to another using `select-window'.\n\
1625 This means that a frame whose focus is redirected to itself is treated\n\
1626 differently from a frame whose focus is redirected to nil; the former\n\
1627 is affected by select-frame, while the latter is not.\n\
1629 The redirection lasts until `redirect-frame-focus' is called to change it.")
1630 (frame
, focus_frame
)
1631 Lisp_Object frame
, focus_frame
;
1633 /* Note that we don't check for a live frame here. It's reasonable
1634 to redirect the focus of a frame you're about to delete, if you
1635 know what other frame should receive those keystrokes. */
1636 CHECK_FRAME (frame
, 0);
1638 if (! NILP (focus_frame
))
1639 CHECK_LIVE_FRAME (focus_frame
, 1);
1641 XFRAME (frame
)->focus_frame
= focus_frame
;
1643 if (frame_rehighlight_hook
)
1644 (*frame_rehighlight_hook
) (XFRAME (frame
));
1650 DEFUN ("frame-focus", Fframe_focus
, Sframe_focus
, 1, 1, 0,
1651 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1652 This returns nil if FRAME's focus is not redirected.\n\
1653 See `redirect-frame-focus'.")
1657 CHECK_LIVE_FRAME (frame
, 0);
1659 return FRAME_FOCUS_FRAME (XFRAME (frame
));
1664 /* Return the value of frame parameter PROP in frame FRAME. */
1667 get_frame_param (frame
, prop
)
1668 register struct frame
*frame
;
1671 register Lisp_Object tem
;
1673 tem
= Fassq (prop
, frame
->param_alist
);
1679 /* Return the buffer-predicate of the selected frame. */
1682 frame_buffer_predicate ()
1684 return selected_frame
->buffer_predicate
;
1687 /* Return the buffer-list of the selected frame. */
1690 frame_buffer_list ()
1692 return selected_frame
->buffer_list
;
1695 /* Set the buffer-list of the selected frame. */
1698 set_frame_buffer_list (list
)
1701 selected_frame
->buffer_list
= list
;
1704 /* Discard BUFFER from the buffer-list of each frame. */
1707 frames_discard_buffer (buffer
)
1710 Lisp_Object frame
, tail
;
1712 FOR_EACH_FRAME (tail
, frame
)
1714 XFRAME (frame
)->buffer_list
1715 = Fdelq (buffer
, XFRAME (frame
)->buffer_list
);
1719 /* Move BUFFER to the end of the buffer-list of each frame. */
1722 frames_bury_buffer (buffer
)
1725 Lisp_Object frame
, tail
;
1727 FOR_EACH_FRAME (tail
, frame
)
1729 XFRAME (frame
)->buffer_list
1730 = nconc2 (Fdelq (buffer
, XFRAME (frame
)->buffer_list
),
1731 Fcons (buffer
, Qnil
));
1735 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1736 If the alist already has an element for PROP, we change it. */
1739 store_in_alist (alistptr
, prop
, val
)
1740 Lisp_Object
*alistptr
, val
;
1743 register Lisp_Object tem
;
1745 tem
= Fassq (prop
, *alistptr
);
1747 *alistptr
= Fcons (Fcons (prop
, val
), *alistptr
);
1753 store_frame_param (f
, prop
, val
)
1755 Lisp_Object prop
, val
;
1757 register Lisp_Object tem
;
1759 if (EQ (prop
, Qbuffer_list
))
1761 f
->buffer_list
= val
;
1765 tem
= Fassq (prop
, f
->param_alist
);
1767 f
->param_alist
= Fcons (Fcons (prop
, val
), f
->param_alist
);
1771 if (EQ (prop
, Qbuffer_predicate
))
1772 f
->buffer_predicate
= val
;
1774 if (! FRAME_WINDOW_P (f
))
1775 if (EQ (prop
, Qmenu_bar_lines
))
1776 set_menu_bar_lines (f
, val
, make_number (FRAME_MENU_BAR_LINES (f
)));
1778 if (EQ (prop
, Qminibuffer
) && WINDOWP (val
))
1780 if (! MINI_WINDOW_P (XWINDOW (val
)))
1781 error ("Surrogate minibuffer windows must be minibuffer windows.");
1783 if (FRAME_HAS_MINIBUF_P (f
) || FRAME_MINIBUF_ONLY_P (f
)
1784 && !EQ (val
, f
->minibuffer_window
))
1785 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1787 /* Install the chosen minibuffer window, with proper buffer. */
1788 f
->minibuffer_window
= val
;
1792 DEFUN ("frame-parameters", Fframe_parameters
, Sframe_parameters
, 0, 1, 0,
1793 "Return the parameters-alist of frame FRAME.\n\
1794 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1795 The meaningful PARMs depend on the kind of frame.\n\
1796 If FRAME is omitted, return information on the currently selected frame.")
1804 if (EQ (frame
, Qnil
))
1808 CHECK_FRAME (frame
, 0);
1812 if (!FRAME_LIVE_P (f
))
1815 alist
= Fcopy_alist (f
->param_alist
);
1817 if (FRAME_MSDOS_P (f
))
1819 static char *colornames
[16] =
1821 "black", "blue", "green", "cyan", "red", "magenta", "brown",
1822 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
1823 "lightred", "lightmagenta", "yellow", "white"
1825 store_in_alist (&alist
, intern ("foreground-color"),
1826 build_string (colornames
[FRAME_FOREGROUND_PIXEL (f
)]));
1827 store_in_alist (&alist
, intern ("background-color"),
1828 build_string (colornames
[FRAME_BACKGROUND_PIXEL (f
)]));
1830 store_in_alist (&alist
, intern ("font"), build_string ("default"));
1832 store_in_alist (&alist
, Qname
, f
->name
);
1833 height
= (FRAME_NEW_HEIGHT (f
) ? FRAME_NEW_HEIGHT (f
) : FRAME_HEIGHT (f
));
1834 store_in_alist (&alist
, Qheight
, make_number (height
));
1835 width
= (FRAME_NEW_WIDTH (f
) ? FRAME_NEW_WIDTH (f
) : FRAME_WIDTH (f
));
1836 store_in_alist (&alist
, Qwidth
, make_number (width
));
1837 store_in_alist (&alist
, Qmodeline
, (FRAME_WANTS_MODELINE_P (f
) ? Qt
: Qnil
));
1838 store_in_alist (&alist
, Qminibuffer
,
1839 (! FRAME_HAS_MINIBUF_P (f
) ? Qnil
1840 : FRAME_MINIBUF_ONLY_P (f
) ? Qonly
1841 : FRAME_MINIBUF_WINDOW (f
)));
1842 store_in_alist (&alist
, Qunsplittable
, (FRAME_NO_SPLIT_P (f
) ? Qt
: Qnil
));
1843 store_in_alist (&alist
, Qbuffer_list
, frame_buffer_list ());
1845 /* I think this should be done with a hook. */
1846 #ifdef HAVE_WINDOW_SYSTEM
1847 if (FRAME_WINDOW_P (f
))
1848 x_report_frame_params (f
, &alist
);
1852 /* This ought to be correct in f->param_alist for an X frame. */
1854 XSETFASTINT (lines
, FRAME_MENU_BAR_LINES (f
));
1855 store_in_alist (&alist
, Qmenu_bar_lines
, lines
);
1860 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters
,
1861 Smodify_frame_parameters
, 2, 2, 0,
1862 "Modify the parameters of frame FRAME according to ALIST.\n\
1863 ALIST is an alist of parameters to change and their new values.\n\
1864 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
1865 The meaningful PARMs depend on the kind of frame.\n\
1866 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
1867 so that `frame-parameters' will return them.")
1869 Lisp_Object frame
, alist
;
1872 register Lisp_Object tail
, elt
, prop
, val
;
1874 if (EQ (frame
, Qnil
))
1878 CHECK_LIVE_FRAME (frame
, 0);
1882 /* I think this should be done with a hook. */
1883 #ifdef HAVE_WINDOW_SYSTEM
1884 if (FRAME_WINDOW_P (f
))
1885 x_set_frame_parameters (f
, alist
);
1889 if (FRAME_MSDOS_P (f
))
1890 IT_set_frame_parameters (f
, alist
);
1894 int length
= XINT (Flength (alist
));
1897 = (Lisp_Object
*) alloca (length
* sizeof (Lisp_Object
));
1899 = (Lisp_Object
*) alloca (length
* sizeof (Lisp_Object
));
1901 /* Extract parm names and values into those vectors. */
1904 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
1906 Lisp_Object elt
, prop
, val
;
1909 parms
[i
] = Fcar (elt
);
1910 values
[i
] = Fcdr (elt
);
1914 /* Now process them in reverse of specified order. */
1915 for (i
--; i
>= 0; i
--)
1919 store_frame_param (f
, prop
, val
);
1926 DEFUN ("frame-char-height", Fframe_char_height
, Sframe_char_height
,
1928 "Height in pixels of a line in the font in frame FRAME.\n\
1929 If FRAME is omitted, the selected frame is used.\n\
1930 For a terminal frame, the value is always 1.")
1940 CHECK_FRAME (frame
, 0);
1944 #ifdef HAVE_WINDOW_SYSTEM
1945 if (FRAME_WINDOW_P (f
))
1946 return make_number (x_char_height (f
));
1949 return make_number (1);
1953 DEFUN ("frame-char-width", Fframe_char_width
, Sframe_char_width
,
1955 "Width in pixels of characters in the font in frame FRAME.\n\
1956 If FRAME is omitted, the selected frame is used.\n\
1957 The width is the same for all characters, because\n\
1958 currently Emacs supports only fixed-width fonts.\n\
1959 For a terminal screen, the value is always 1.")
1969 CHECK_FRAME (frame
, 0);
1973 #ifdef HAVE_WINDOW_SYSTEM
1974 if (FRAME_WINDOW_P (f
))
1975 return make_number (x_char_width (f
));
1978 return make_number (1);
1981 DEFUN ("frame-pixel-height", Fframe_pixel_height
,
1982 Sframe_pixel_height
, 0, 1, 0,
1983 "Return a FRAME's height in pixels.\n\
1984 For a terminal frame, the result really gives the height in characters.\n\
1985 If FRAME is omitted, the selected frame is used.")
1995 CHECK_FRAME (frame
, 0);
1999 #ifdef HAVE_WINDOW_SYSTEM
2000 if (FRAME_WINDOW_P (f
))
2001 return make_number (x_pixel_height (f
));
2004 return make_number (FRAME_HEIGHT (f
));
2007 DEFUN ("frame-pixel-width", Fframe_pixel_width
,
2008 Sframe_pixel_width
, 0, 1, 0,
2009 "Return FRAME's width in pixels.\n\
2010 For a terminal frame, the result really gives the width in characters.\n\
2011 If FRAME is omitted, the selected frame is used.")
2021 CHECK_FRAME (frame
, 0);
2025 #ifdef HAVE_WINDOW_SYSTEM
2026 if (FRAME_WINDOW_P (f
))
2027 return make_number (x_pixel_width (f
));
2030 return make_number (FRAME_WIDTH (f
));
2033 DEFUN ("set-frame-height", Fset_frame_height
, Sset_frame_height
, 2, 3, 0,
2034 "Specify that the frame FRAME has LINES lines.\n\
2035 Optional third arg non-nil means that redisplay should use LINES lines\n\
2036 but that the idea of the actual height of the frame should not be changed.")
2037 (frame
, lines
, pretend
)
2038 Lisp_Object frame
, lines
, pretend
;
2040 register struct frame
*f
;
2042 CHECK_NUMBER (lines
, 0);
2047 CHECK_LIVE_FRAME (frame
, 0);
2051 /* I think this should be done with a hook. */
2052 #ifdef HAVE_WINDOW_SYSTEM
2053 if (FRAME_WINDOW_P (f
))
2055 if (XINT (lines
) != f
->height
)
2056 x_set_window_size (f
, 1, f
->width
, XINT (lines
));
2060 change_frame_size (f
, XINT (lines
), 0, !NILP (pretend
), 0);
2064 DEFUN ("set-frame-width", Fset_frame_width
, Sset_frame_width
, 2, 3, 0,
2065 "Specify that the frame FRAME has COLS columns.\n\
2066 Optional third arg non-nil means that redisplay should use COLS columns\n\
2067 but that the idea of the actual width of the frame should not be changed.")
2068 (frame
, cols
, pretend
)
2069 Lisp_Object frame
, cols
, pretend
;
2071 register struct frame
*f
;
2072 CHECK_NUMBER (cols
, 0);
2077 CHECK_LIVE_FRAME (frame
, 0);
2081 /* I think this should be done with a hook. */
2082 #ifdef HAVE_WINDOW_SYSTEM
2083 if (FRAME_WINDOW_P (f
))
2085 if (XINT (cols
) != f
->width
)
2086 x_set_window_size (f
, 1, XINT (cols
), f
->height
);
2090 change_frame_size (f
, 0, XINT (cols
), !NILP (pretend
), 0);
2094 DEFUN ("set-frame-size", Fset_frame_size
, Sset_frame_size
, 3, 3, 0,
2095 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2097 Lisp_Object frame
, cols
, rows
;
2099 register struct frame
*f
;
2102 CHECK_LIVE_FRAME (frame
, 0);
2103 CHECK_NUMBER (cols
, 2);
2104 CHECK_NUMBER (rows
, 1);
2107 /* I think this should be done with a hook. */
2108 #ifdef HAVE_WINDOW_SYSTEM
2109 if (FRAME_WINDOW_P (f
))
2111 if (XINT (rows
) != f
->height
|| XINT (cols
) != f
->width
2112 || FRAME_NEW_HEIGHT (f
) || FRAME_NEW_WIDTH (f
))
2113 x_set_window_size (f
, 1, XINT (cols
), XINT (rows
));
2117 change_frame_size (f
, XINT (rows
), XINT (cols
), 0, 0);
2122 DEFUN ("set-frame-position", Fset_frame_position
,
2123 Sset_frame_position
, 3, 3, 0,
2124 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2125 This is actually the position of the upper left corner of the frame.\n\
2126 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2127 the rightmost or bottommost possible position (that stays within the screen).")
2128 (frame
, xoffset
, yoffset
)
2129 Lisp_Object frame
, xoffset
, yoffset
;
2131 register struct frame
*f
;
2134 CHECK_LIVE_FRAME (frame
, 0);
2135 CHECK_NUMBER (xoffset
, 1);
2136 CHECK_NUMBER (yoffset
, 2);
2139 /* I think this should be done with a hook. */
2140 #ifdef HAVE_WINDOW_SYSTEM
2141 if (FRAME_WINDOW_P (f
))
2142 x_set_offset (f
, XINT (xoffset
), XINT (yoffset
), 1);
2153 staticpro (&Vframe_list
);
2155 DEFVAR_LISP ("terminal-frame", &Vterminal_frame
,
2156 "The initial frame-object, which represents Emacs's stdout.");
2158 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified
,
2159 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2160 Vemacs_iconified
= Qnil
;
2162 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame
,
2163 "Minibufferless frames use this frame's minibuffer.\n\
2165 Emacs cannot create minibufferless frames unless this is set to an\n\
2166 appropriate surrogate.\n\
2168 Emacs consults this variable only when creating minibufferless\n\
2169 frames; once the frame is created, it sticks with its assigned\n\
2170 minibuffer, no matter what this variable is set to. This means that\n\
2171 this variable doesn't necessarily say anything meaningful about the\n\
2172 current set of frames, or where the minibuffer is currently being\n\
2175 defsubr (&Sactive_minibuffer_window
);
2177 defsubr (&Sframe_live_p
);
2178 defsubr (&Smake_terminal_frame
);
2179 defsubr (&Shandle_switch_frame
);
2180 defsubr (&Signore_event
);
2181 defsubr (&Sselect_frame
);
2182 defsubr (&Sselected_frame
);
2183 defsubr (&Swindow_frame
);
2184 defsubr (&Sframe_root_window
);
2185 defsubr (&Sframe_first_window
);
2186 defsubr (&Sframe_selected_window
);
2187 defsubr (&Sset_frame_selected_window
);
2188 defsubr (&Sframe_list
);
2189 defsubr (&Snext_frame
);
2190 defsubr (&Sprevious_frame
);
2191 defsubr (&Sdelete_frame
);
2192 defsubr (&Smouse_position
);
2193 defsubr (&Smouse_pixel_position
);
2194 defsubr (&Sset_mouse_position
);
2195 defsubr (&Sset_mouse_pixel_position
);
2197 defsubr (&Sframe_configuration
);
2198 defsubr (&Srestore_frame_configuration
);
2200 defsubr (&Smake_frame_visible
);
2201 defsubr (&Smake_frame_invisible
);
2202 defsubr (&Siconify_frame
);
2203 defsubr (&Sframe_visible_p
);
2204 defsubr (&Svisible_frame_list
);
2205 defsubr (&Sraise_frame
);
2206 defsubr (&Slower_frame
);
2207 defsubr (&Sredirect_frame_focus
);
2208 defsubr (&Sframe_focus
);
2209 defsubr (&Sframe_parameters
);
2210 defsubr (&Smodify_frame_parameters
);
2211 defsubr (&Sframe_char_height
);
2212 defsubr (&Sframe_char_width
);
2213 defsubr (&Sframe_pixel_height
);
2214 defsubr (&Sframe_pixel_width
);
2215 defsubr (&Sset_frame_height
);
2216 defsubr (&Sset_frame_width
);
2217 defsubr (&Sset_frame_size
);
2218 defsubr (&Sset_frame_position
);
2223 initial_define_lispy_key (global_map
, "switch-frame", "handle-switch-frame");
2224 initial_define_lispy_key (global_map
, "delete-frame", "handle-delete-frame");
2225 initial_define_lispy_key (global_map
, "iconify-frame", "ignore-event");
2226 initial_define_lispy_key (global_map
, "make-frame-visible", "ignore-event");