(do_switch_frame): If selected frame has a mini-window,
[emacs.git] / src / frame.c
blob6850c92dc276450aa365b754534dde08b97c28a0
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000 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)
9 any later version.
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. */
21 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "charset.h"
26 #ifdef HAVE_X_WINDOWS
27 #include "xterm.h"
28 #endif
29 #ifdef WINDOWSNT
30 #include "w32term.h"
31 #endif
32 #ifdef macintosh
33 #include "macterm.h"
34 #endif
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #ifdef HAVE_WINDOW_SYSTEM
41 #include "fontset.h"
42 #endif
43 #include "termhooks.h"
44 #include "dispextern.h"
45 #include "window.h"
46 #ifdef MSDOS
47 #include "msdos.h"
48 #include "dosfns.h"
49 #endif
51 Lisp_Object Qframep;
52 Lisp_Object Qframe_live_p;
53 Lisp_Object Qheight;
54 Lisp_Object Qicon;
55 Lisp_Object Qminibuffer;
56 Lisp_Object Qmodeline;
57 Lisp_Object Qname;
58 Lisp_Object Qonly;
59 Lisp_Object Qunsplittable;
60 Lisp_Object Qmenu_bar_lines;
61 Lisp_Object Qtool_bar_lines;
62 Lisp_Object Qwidth;
63 Lisp_Object Qx;
64 Lisp_Object Qw32;
65 Lisp_Object Qpc;
66 Lisp_Object Qmac;
67 Lisp_Object Qvisible;
68 Lisp_Object Qbuffer_predicate;
69 Lisp_Object Qbuffer_list;
70 Lisp_Object Qtitle;
71 Lisp_Object Qdisplay_type;
72 Lisp_Object Qbackground_mode;
73 Lisp_Object Qinhibit_default_face_x_resources;
75 Lisp_Object Vterminal_frame;
76 Lisp_Object Vdefault_frame_alist;
77 Lisp_Object Vmouse_position_function;
79 static void
80 set_menu_bar_lines_1 (window, n)
81 Lisp_Object window;
82 int n;
84 struct window *w = XWINDOW (window);
86 XSETFASTINT (w->last_modified, 0);
87 XSETFASTINT (w->top, XFASTINT (w->top) + n);
88 XSETFASTINT (w->height, XFASTINT (w->height) - n);
90 if (INTEGERP (w->orig_top))
91 XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
92 if (INTEGERP (w->orig_height))
93 XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);
95 /* Handle just the top child in a vertical split. */
96 if (!NILP (w->vchild))
97 set_menu_bar_lines_1 (w->vchild, n);
99 /* Adjust all children in a horizontal split. */
100 for (window = w->hchild; !NILP (window); window = w->next)
102 w = XWINDOW (window);
103 set_menu_bar_lines_1 (window, n);
107 void
108 set_menu_bar_lines (f, value, oldval)
109 struct frame *f;
110 Lisp_Object value, oldval;
112 int nlines;
113 int olines = FRAME_MENU_BAR_LINES (f);
115 /* Right now, menu bars don't work properly in minibuf-only frames;
116 most of the commands try to apply themselves to the minibuffer
117 frame itself, and get an error because you can't switch buffers
118 in or split the minibuffer window. */
119 if (FRAME_MINIBUF_ONLY_P (f))
120 return;
122 if (INTEGERP (value))
123 nlines = XINT (value);
124 else
125 nlines = 0;
127 if (nlines != olines)
129 windows_or_buffers_changed++;
130 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
131 FRAME_MENU_BAR_LINES (f) = nlines;
132 set_menu_bar_lines_1 (f->root_window, nlines - olines);
133 adjust_glyphs (f);
137 Lisp_Object Vemacs_iconified;
138 Lisp_Object Vframe_list;
140 struct x_output tty_display;
142 extern Lisp_Object Vminibuffer_list;
143 extern Lisp_Object get_minibuffer ();
144 extern Lisp_Object Fhandle_switch_frame ();
145 extern Lisp_Object Fredirect_frame_focus ();
146 extern Lisp_Object x_get_focus_frame ();
148 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
149 "Return non-nil if OBJECT is a frame.\n\
150 Value is t for a termcap frame (a character-only terminal),\n\
151 `x' for an Emacs frame that is really an X window,\n\
152 `w32' for an Emacs frame that is a window on MS-Windows display,\n\
153 `mac' for an Emacs frame on a Macintosh display,\n\
154 `pc' for a direct-write MS-DOS frame.\n\
155 See also `frame-live-p'.")
156 (object)
157 Lisp_Object object;
159 if (!FRAMEP (object))
160 return Qnil;
161 switch (XFRAME (object)->output_method)
163 case output_termcap:
164 return Qt;
165 case output_x_window:
166 return Qx;
167 case output_w32:
168 return Qw32;
169 case output_msdos_raw:
170 return Qpc;
171 case output_mac:
172 return Qmac;
173 default:
174 abort ();
178 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
179 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
180 Value is nil if OBJECT is not a live frame. If object is a live\n\
181 frame, the return value indicates what sort of output device it is\n\
182 displayed on. Value is t for a termcap frame (a character-only\n\
183 terminal), `x' for an Emacs frame being displayed in an X window.")
184 (object)
185 Lisp_Object object;
187 return ((FRAMEP (object)
188 && FRAME_LIVE_P (XFRAME (object)))
189 ? Fframep (object)
190 : Qnil);
193 struct frame *
194 make_frame (mini_p)
195 int mini_p;
197 Lisp_Object frame;
198 register struct frame *f;
199 register Lisp_Object root_window;
200 register Lisp_Object mini_window;
201 register struct Lisp_Vector *vec;
202 int i;
204 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
205 for (i = 0; i < VECSIZE (struct frame); i++)
206 XSETFASTINT (vec->contents[i], 0);
207 vec->size = VECSIZE (struct frame);
208 f = (struct frame *)vec;
209 XSETFRAME (frame, f);
211 f->desired_matrix = 0;
212 f->current_matrix = 0;
213 f->desired_pool = 0;
214 f->current_pool = 0;
215 f->glyphs_initialized_p = 0;
216 f->decode_mode_spec_buffer = 0;
217 f->visible = 0;
218 f->async_visible = 0;
219 f->output_data.nothing = 0;
220 f->iconified = 0;
221 f->async_iconified = 0;
222 f->wants_modeline = 1;
223 f->auto_raise = 0;
224 f->auto_lower = 0;
225 f->no_split = 0;
226 f->garbaged = 1;
227 f->has_minibuffer = mini_p;
228 f->focus_frame = Qnil;
229 f->explicit_name = 0;
230 f->can_have_scroll_bars = 0;
231 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
232 f->param_alist = Qnil;
233 f->scroll_bars = Qnil;
234 f->condemned_scroll_bars = Qnil;
235 f->face_alist = Qnil;
236 f->face_cache = NULL;
237 f->menu_bar_items = Qnil;
238 f->menu_bar_vector = Qnil;
239 f->menu_bar_items_used = 0;
240 f->buffer_predicate = Qnil;
241 f->buffer_list = Qnil;
242 #ifdef MULTI_KBOARD
243 f->kboard = initial_kboard;
244 #endif
245 f->namebuf = 0;
246 f->title = Qnil;
247 f->menu_bar_window = Qnil;
248 f->tool_bar_window = Qnil;
249 f->tool_bar_items = Qnil;
250 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
251 f->n_tool_bar_items = 0;
253 root_window = make_window ();
254 if (mini_p)
256 mini_window = make_window ();
257 XWINDOW (root_window)->next = mini_window;
258 XWINDOW (mini_window)->prev = root_window;
259 XWINDOW (mini_window)->mini_p = Qt;
260 XWINDOW (mini_window)->frame = frame;
261 f->minibuffer_window = mini_window;
263 else
265 mini_window = Qnil;
266 XWINDOW (root_window)->next = Qnil;
267 f->minibuffer_window = Qnil;
270 XWINDOW (root_window)->frame = frame;
272 /* 10 is arbitrary,
273 just so that there is "something there."
274 Correct size will be set up later with change_frame_size. */
276 SET_FRAME_WIDTH (f, 10);
277 f->height = 10;
279 XSETFASTINT (XWINDOW (root_window)->width, 10);
280 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
282 if (mini_p)
284 XSETFASTINT (XWINDOW (mini_window)->width, 10);
285 XSETFASTINT (XWINDOW (mini_window)->top, 9);
286 XSETFASTINT (XWINDOW (mini_window)->height, 1);
289 /* Choose a buffer for the frame's root window. */
291 Lisp_Object buf;
293 XWINDOW (root_window)->buffer = Qt;
294 buf = Fcurrent_buffer ();
295 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
296 a space), try to find another one. */
297 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
298 buf = Fother_buffer (buf, Qnil, Qnil);
300 /* Use set_window_buffer, not Fset_window_buffer, and don't let
301 hooks be run by it. The reason is that the whole frame/window
302 arrangement is not yet fully intialized at this point. Windows
303 don't have the right size, glyph matrices aren't initialized
304 etc. Running Lisp functions at this point surely ends in a
305 SEGV. */
306 set_window_buffer (root_window, buf, 0);
307 f->buffer_list = Fcons (buf, Qnil);
310 if (mini_p)
312 XWINDOW (mini_window)->buffer = Qt;
313 set_window_buffer (mini_window,
314 (NILP (Vminibuffer_list)
315 ? get_minibuffer (0)
316 : Fcar (Vminibuffer_list)),
320 f->root_window = root_window;
321 f->selected_window = root_window;
322 /* Make sure this window seems more recently used than
323 a newly-created, never-selected window. */
324 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
326 return f;
329 #ifdef HAVE_WINDOW_SYSTEM
330 /* Make a frame using a separate minibuffer window on another frame.
331 MINI_WINDOW is the minibuffer window to use. nil means use the
332 default (the global minibuffer). */
334 struct frame *
335 make_frame_without_minibuffer (mini_window, kb, display)
336 register Lisp_Object mini_window;
337 KBOARD *kb;
338 Lisp_Object display;
340 register struct frame *f;
341 struct gcpro gcpro1;
343 if (!NILP (mini_window))
344 CHECK_LIVE_WINDOW (mini_window, 0);
346 #ifdef MULTI_KBOARD
347 if (!NILP (mini_window)
348 && XFRAME (XWINDOW (mini_window)->frame)->kboard != kb)
349 error ("frame and minibuffer must be on the same display");
350 #endif
352 /* Make a frame containing just a root window. */
353 f = make_frame (0);
355 if (NILP (mini_window))
357 /* Use default-minibuffer-frame if possible. */
358 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
359 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
361 Lisp_Object frame_dummy;
363 XSETFRAME (frame_dummy, f);
364 GCPRO1 (frame_dummy);
365 /* If there's no minibuffer frame to use, create one. */
366 kb->Vdefault_minibuffer_frame =
367 call1 (intern ("make-initial-minibuffer-frame"), display);
368 UNGCPRO;
371 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
374 f->minibuffer_window = mini_window;
376 /* Make the chosen minibuffer window display the proper minibuffer,
377 unless it is already showing a minibuffer. */
378 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
379 Fset_window_buffer (mini_window,
380 (NILP (Vminibuffer_list)
381 ? get_minibuffer (0)
382 : Fcar (Vminibuffer_list)));
383 return f;
386 /* Make a frame containing only a minibuffer window. */
388 struct frame *
389 make_minibuffer_frame ()
391 /* First make a frame containing just a root window, no minibuffer. */
393 register struct frame *f = make_frame (0);
394 register Lisp_Object mini_window;
395 register Lisp_Object frame;
397 XSETFRAME (frame, f);
399 f->auto_raise = 0;
400 f->auto_lower = 0;
401 f->no_split = 1;
402 f->wants_modeline = 0;
403 f->has_minibuffer = 1;
405 /* Now label the root window as also being the minibuffer.
406 Avoid infinite looping on the window chain by marking next pointer
407 as nil. */
409 mini_window = f->minibuffer_window = f->root_window;
410 XWINDOW (mini_window)->mini_p = Qt;
411 XWINDOW (mini_window)->next = Qnil;
412 XWINDOW (mini_window)->prev = Qnil;
413 XWINDOW (mini_window)->frame = frame;
415 /* Put the proper buffer in that window. */
417 Fset_window_buffer (mini_window,
418 (NILP (Vminibuffer_list)
419 ? get_minibuffer (0)
420 : Fcar (Vminibuffer_list)));
421 return f;
423 #endif /* HAVE_WINDOW_SYSTEM */
425 /* Construct a frame that refers to the terminal (stdin and stdout). */
427 static int terminal_frame_count;
429 struct frame *
430 make_terminal_frame ()
432 register struct frame *f;
433 Lisp_Object frame;
434 char name[20];
436 #ifdef MULTI_KBOARD
437 if (!initial_kboard)
439 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
440 init_kboard (initial_kboard);
441 initial_kboard->next_kboard = all_kboards;
442 all_kboards = initial_kboard;
444 #endif
446 /* The first call must initialize Vframe_list. */
447 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
448 Vframe_list = Qnil;
450 f = make_frame (1);
452 XSETFRAME (frame, f);
453 Vframe_list = Fcons (frame, Vframe_list);
455 terminal_frame_count++;
456 sprintf (name, "F%d", terminal_frame_count);
457 f->name = build_string (name);
459 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
460 f->async_visible = 1; /* Don't let visible be cleared later. */
461 #ifdef MSDOS
462 f->output_data.x = &the_only_x_display;
463 if (!inhibit_window_system
464 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
465 || XFRAME (selected_frame)->output_method == output_msdos_raw))
467 f->output_method = output_msdos_raw;
468 /* This initialization of foreground and background pixels is
469 only important for the initial frame created in temacs. If
470 we don't do that, we get black background and foreground in
471 the dumped Emacs because the_only_x_display is a static
472 variable, hence it is born all-zeroes, and zero is the code
473 for the black color. Other frames all inherit their pixels
474 from what's already in the_only_x_display. */
475 if ((!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame)))
476 && f->output_data.x->background_pixel == 0
477 && f->output_data.x->foreground_pixel == 0)
479 f->output_data.x->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
480 f->output_data.x->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
483 else
484 f->output_method = output_termcap;
485 #else
486 #ifdef WINDOWSNT
487 f->output_method = output_termcap;
488 f->output_data.x = &tty_display;
489 #else
490 #ifdef macintosh
491 make_mac_terminal_frame (f);
492 #else
493 f->output_data.x = &tty_display;
494 #endif /* macintosh */
495 #endif /* WINDOWSNT */
496 #endif /* MSDOS */
498 if (!noninteractive)
499 init_frame_faces (f);
501 return f;
504 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
505 1, 1, 0, "Create an additional terminal frame.\n\
506 You can create multiple frames on a text-only terminal in this way.\n\
507 Only the selected terminal frame is actually displayed.\n\
508 This function takes one argument, an alist specifying frame parameters.\n\
509 In practice, generally you don't need to specify any parameters.\n\
510 Note that changing the size of one terminal frame automatically affects all.")
511 (parms)
512 Lisp_Object parms;
514 struct frame *f;
515 Lisp_Object frame, tem;
516 struct frame *sf = SELECTED_FRAME ();
518 #ifdef MSDOS
519 if (sf->output_method != output_msdos_raw
520 && sf->output_method != output_termcap)
521 abort ();
522 #else /* not MSDOS */
524 #ifdef macintosh
525 if (sf->output_method != output_mac)
526 error ("Not running on a Macintosh screen; cannot make a new Macintosh frame");
527 #else
528 if (sf->output_method != output_termcap)
529 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
530 #endif
531 #endif /* not MSDOS */
533 f = make_terminal_frame ();
535 change_frame_size (f, FRAME_HEIGHT (sf),
536 FRAME_WIDTH (sf), 0, 0, 0);
537 adjust_glyphs (f);
538 calculate_costs (f);
539 XSETFRAME (frame, f);
540 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
541 Fmodify_frame_parameters (frame, parms);
543 /* Make the frame face alist be frame-specific, so that each
544 frame could change its face definitions independently. */
545 f->face_alist = Fcopy_alist (sf->face_alist);
546 /* Simple Fcopy_alist isn't enough, because we need the contents of
547 the vectors which are the CDRs of associations in face_alist to
548 be copied as well. */
549 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
550 XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
551 return frame;
554 Lisp_Object
555 do_switch_frame (frame, no_enter, track)
556 Lisp_Object frame, no_enter;
557 int track;
559 struct frame *sf = SELECTED_FRAME ();
561 /* If FRAME is a switch-frame event, extract the frame we should
562 switch to. */
563 if (CONSP (frame)
564 && EQ (XCAR (frame), Qswitch_frame)
565 && CONSP (XCDR (frame)))
566 frame = XCAR (XCDR (frame));
568 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
569 a switch-frame event to arrive after a frame is no longer live,
570 especially when deleting the initial frame during startup. */
571 CHECK_FRAME (frame, 0);
572 if (! FRAME_LIVE_P (XFRAME (frame)))
573 return Qnil;
575 if (sf == XFRAME (frame))
576 return frame;
578 /* This is too greedy; it causes inappropriate focus redirection
579 that's hard to get rid of. */
580 #if 0
581 /* If a frame's focus has been redirected toward the currently
582 selected frame, we should change the redirection to point to the
583 newly selected frame. This means that if the focus is redirected
584 from a minibufferless frame to a surrogate minibuffer frame, we
585 can use `other-window' to switch between all the frames using
586 that minibuffer frame, and the focus redirection will follow us
587 around. */
588 if (track)
590 Lisp_Object tail;
592 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
594 Lisp_Object focus;
596 if (!FRAMEP (XCAR (tail)))
597 abort ();
599 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
601 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
602 Fredirect_frame_focus (XCAR (tail), frame);
605 #else /* ! 0 */
606 /* Instead, apply it only to the frame we're pointing to. */
607 #ifdef HAVE_WINDOW_SYSTEM
608 if (track && (FRAME_WINDOW_P (XFRAME (frame))))
610 Lisp_Object focus, xfocus;
612 xfocus = x_get_focus_frame (XFRAME (frame));
613 if (FRAMEP (xfocus))
615 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
616 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
617 Fredirect_frame_focus (xfocus, frame);
620 #endif /* HAVE_X_WINDOWS */
621 #endif /* ! 0 */
623 if (FRAME_HAS_MINIBUF_P (sf))
624 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
626 selected_frame = frame;
627 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
628 last_nonminibuf_frame = XFRAME (selected_frame);
630 Fselect_window (XFRAME (frame)->selected_window);
632 /* We want to make sure that the next event generates a frame-switch
633 event to the appropriate frame. This seems kludgy to me, but
634 before you take it out, make sure that evaluating something like
635 (select-window (frame-root-window (new-frame))) doesn't end up
636 with your typing being interpreted in the new frame instead of
637 the one you're actually typing in. */
638 internal_last_event_frame = Qnil;
640 return frame;
643 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
644 "Select the frame FRAME.\n\
645 Subsequent editing commands apply to its selected window.\n\
646 The selection of FRAME lasts until the next time the user does\n\
647 something to select a different frame, or until the next time this\n\
648 function is called.")
649 (frame, no_enter)
650 Lisp_Object frame, no_enter;
652 return do_switch_frame (frame, no_enter, 1);
656 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
657 "Handle a switch-frame event EVENT.\n\
658 Switch-frame events are usually bound to this function.\n\
659 A switch-frame event tells Emacs that the window manager has requested\n\
660 that the user's events be directed to the frame mentioned in the event.\n\
661 This function selects the selected window of the frame of EVENT.\n\
663 If EVENT is frame object, handle it as if it were a switch-frame event\n\
664 to that frame.")
665 (event, no_enter)
666 Lisp_Object event, no_enter;
668 /* Preserve prefix arg that the command loop just cleared. */
669 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
670 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
671 return do_switch_frame (event, no_enter, 0);
674 DEFUN ("ignore-event", Fignore_event, Signore_event, 0, 0, "",
675 "Do nothing, but preserve any prefix argument already specified.\n\
676 This is a suitable binding for iconify-frame and make-frame-visible.")
679 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
680 return Qnil;
683 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
684 "Return the frame that is now selected.")
687 return selected_frame;
690 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
691 "Return the frame object that window WINDOW is on.")
692 (window)
693 Lisp_Object window;
695 CHECK_LIVE_WINDOW (window, 0);
696 return XWINDOW (window)->frame;
699 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
700 "Returns the topmost, leftmost window of FRAME.\n\
701 If omitted, FRAME defaults to the currently selected frame.")
702 (frame)
703 Lisp_Object frame;
705 Lisp_Object w;
707 if (NILP (frame))
708 w = SELECTED_FRAME ()->root_window;
709 else
711 CHECK_LIVE_FRAME (frame, 0);
712 w = XFRAME (frame)->root_window;
714 while (NILP (XWINDOW (w)->buffer))
716 if (! NILP (XWINDOW (w)->hchild))
717 w = XWINDOW (w)->hchild;
718 else if (! NILP (XWINDOW (w)->vchild))
719 w = XWINDOW (w)->vchild;
720 else
721 abort ();
723 return w;
726 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
727 Sactive_minibuffer_window, 0, 0, 0,
728 "Return the currently active minibuffer window, or nil if none.")
731 return minibuf_level ? minibuf_window : Qnil;
734 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
735 "Returns the root-window of FRAME.\n\
736 If omitted, FRAME defaults to the currently selected frame.")
737 (frame)
738 Lisp_Object frame;
740 Lisp_Object window;
742 if (NILP (frame))
743 window = SELECTED_FRAME ()->root_window;
744 else
746 CHECK_LIVE_FRAME (frame, 0);
747 window = XFRAME (frame)->root_window;
750 return window;
753 DEFUN ("frame-selected-window", Fframe_selected_window,
754 Sframe_selected_window, 0, 1, 0,
755 "Return the selected window of frame object FRAME.\n\
756 If omitted, FRAME defaults to the currently selected frame.")
757 (frame)
758 Lisp_Object frame;
760 Lisp_Object window;
762 if (NILP (frame))
763 window = SELECTED_FRAME ()->selected_window;
764 else
766 CHECK_LIVE_FRAME (frame, 0);
767 window = XFRAME (frame)->selected_window;
770 return window;
773 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
774 Sset_frame_selected_window, 2, 2, 0,
775 "Set the selected window of frame object FRAME to WINDOW.\n\
776 If FRAME is nil, the selected frame is used.\n\
777 If FRAME is the selected frame, this makes WINDOW the selected window.")
778 (frame, window)
779 Lisp_Object frame, window;
781 if (NILP (frame))
782 frame = selected_frame;
784 CHECK_LIVE_FRAME (frame, 0);
785 CHECK_LIVE_WINDOW (window, 1);
787 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
788 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
790 if (EQ (frame, selected_frame))
791 return Fselect_window (window);
793 return XFRAME (frame)->selected_window = window;
796 DEFUN ("frame-list", Fframe_list, Sframe_list,
797 0, 0, 0,
798 "Return a list of all frames.")
801 return Fcopy_sequence (Vframe_list);
804 /* Return the next frame in the frame list after FRAME.
805 If MINIBUF is nil, exclude minibuffer-only frames.
806 If MINIBUF is a window, include only its own frame
807 and any frame now using that window as the minibuffer.
808 If MINIBUF is `visible', include all visible frames.
809 If MINIBUF is 0, include all visible and iconified frames.
810 Otherwise, include all frames. */
812 Lisp_Object
813 next_frame (frame, minibuf)
814 Lisp_Object frame;
815 Lisp_Object minibuf;
817 Lisp_Object tail;
818 int passed = 0;
820 /* There must always be at least one frame in Vframe_list. */
821 if (! CONSP (Vframe_list))
822 abort ();
824 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
825 forever. Forestall that. */
826 CHECK_LIVE_FRAME (frame, 0);
828 while (1)
829 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
831 Lisp_Object f;
833 f = XCAR (tail);
835 if (passed
836 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
838 /* Decide whether this frame is eligible to be returned. */
840 /* If we've looped all the way around without finding any
841 eligible frames, return the original frame. */
842 if (EQ (f, frame))
843 return f;
845 /* Let minibuf decide if this frame is acceptable. */
846 if (NILP (minibuf))
848 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
849 return f;
851 else if (EQ (minibuf, Qvisible))
853 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
854 if (FRAME_VISIBLE_P (XFRAME (f)))
855 return f;
857 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
859 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
860 if (FRAME_VISIBLE_P (XFRAME (f))
861 || FRAME_ICONIFIED_P (XFRAME (f)))
862 return f;
864 else if (WINDOWP (minibuf))
866 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
867 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
868 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
869 FRAME_FOCUS_FRAME (XFRAME (f))))
870 return f;
872 else
873 return f;
876 if (EQ (frame, f))
877 passed++;
881 /* Return the previous frame in the frame list before FRAME.
882 If MINIBUF is nil, exclude minibuffer-only frames.
883 If MINIBUF is a window, include only its own frame
884 and any frame now using that window as the minibuffer.
885 If MINIBUF is `visible', include all visible frames.
886 If MINIBUF is 0, include all visible and iconified frames.
887 Otherwise, include all frames. */
889 Lisp_Object
890 prev_frame (frame, minibuf)
891 Lisp_Object frame;
892 Lisp_Object minibuf;
894 Lisp_Object tail;
895 Lisp_Object prev;
897 /* There must always be at least one frame in Vframe_list. */
898 if (! CONSP (Vframe_list))
899 abort ();
901 prev = Qnil;
902 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
904 Lisp_Object f;
906 f = XCAR (tail);
907 if (!FRAMEP (f))
908 abort ();
910 if (EQ (frame, f) && !NILP (prev))
911 return prev;
913 if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
915 /* Decide whether this frame is eligible to be returned,
916 according to minibuf. */
917 if (NILP (minibuf))
919 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
920 prev = f;
922 else if (WINDOWP (minibuf))
924 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
925 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
926 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
927 FRAME_FOCUS_FRAME (XFRAME (f))))
928 prev = f;
930 else if (EQ (minibuf, Qvisible))
932 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
933 if (FRAME_VISIBLE_P (XFRAME (f)))
934 prev = f;
936 else if (XFASTINT (minibuf) == 0)
938 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
939 if (FRAME_VISIBLE_P (XFRAME (f))
940 || FRAME_ICONIFIED_P (XFRAME (f)))
941 prev = f;
943 else
944 prev = f;
948 /* We've scanned the entire list. */
949 if (NILP (prev))
950 /* We went through the whole frame list without finding a single
951 acceptable frame. Return the original frame. */
952 return frame;
953 else
954 /* There were no acceptable frames in the list before FRAME; otherwise,
955 we would have returned directly from the loop. Since PREV is the last
956 acceptable frame in the list, return it. */
957 return prev;
961 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
962 "Return the next frame in the frame list after FRAME.\n\
963 It considers only frames on the same terminal as FRAME.\n\
964 By default, skip minibuffer-only frames.\n\
965 If omitted, FRAME defaults to the selected frame.\n\
966 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
967 If MINIFRAME is a window, include only its own frame\n\
968 and any frame now using that window as the minibuffer.\n\
969 If MINIFRAME is `visible', include all visible frames.\n\
970 If MINIFRAME is 0, include all visible and iconified frames.\n\
971 Otherwise, include all frames.")
972 (frame, miniframe)
973 Lisp_Object frame, miniframe;
975 if (NILP (frame))
976 frame = selected_frame;
978 CHECK_LIVE_FRAME (frame, 0);
979 return next_frame (frame, miniframe);
982 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
983 "Return the previous frame in the frame list before FRAME.\n\
984 It considers only frames on the same terminal as FRAME.\n\
985 By default, skip minibuffer-only frames.\n\
986 If omitted, FRAME defaults to the selected frame.\n\
987 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
988 If MINIFRAME is a window, include only its own frame\n\
989 and any frame now using that window as the minibuffer.\n\
990 If MINIFRAME is `visible', include all visible frames.\n\
991 If MINIFRAME is 0, include all visible and iconified frames.\n\
992 Otherwise, include all frames.")
993 (frame, miniframe)
994 Lisp_Object frame, miniframe;
996 if (NILP (frame))
997 frame = selected_frame;
998 CHECK_LIVE_FRAME (frame, 0);
999 return prev_frame (frame, miniframe);
1002 /* Return 1 if it is ok to delete frame F;
1003 0 if all frames aside from F are invisible.
1004 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1007 other_visible_frames (f)
1008 FRAME_PTR f;
1010 /* We know the selected frame is visible,
1011 so if F is some other frame, it can't be the sole visible one. */
1012 if (f == SELECTED_FRAME ())
1014 Lisp_Object frames;
1015 int count = 0;
1017 for (frames = Vframe_list;
1018 CONSP (frames);
1019 frames = XCDR (frames))
1021 Lisp_Object this;
1023 this = XCAR (frames);
1024 /* Verify that the frame's window still exists
1025 and we can still talk to it. And note any recent change
1026 in visibility. */
1027 #ifdef HAVE_WINDOW_SYSTEM
1028 if (FRAME_WINDOW_P (XFRAME (this)))
1030 x_sync (XFRAME (this));
1031 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1033 #endif
1035 if (FRAME_VISIBLE_P (XFRAME (this))
1036 || FRAME_ICONIFIED_P (XFRAME (this))
1037 /* Allow deleting the terminal frame when at least
1038 one X frame exists! */
1039 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1040 count++;
1042 return count > 1;
1044 return 1;
1047 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1048 "Delete FRAME, permanently eliminating it from use.\n\
1049 If omitted, FRAME defaults to the selected frame.\n\
1050 A frame may not be deleted if its minibuffer is used by other frames.\n\
1051 Normally, you may not delete a frame if all other frames are invisible,\n\
1052 but if the second optional argument FORCE is non-nil, you may do so.\n\
1054 This function runs `delete-frame-hook' before actually deleting the\n\
1055 frame. The hook is called with one argument FRAME.")
1056 (frame, force)
1057 Lisp_Object frame, force;
1059 struct frame *f;
1060 struct frame *sf = SELECTED_FRAME ();
1061 int minibuffer_selected;
1063 if (EQ (frame, Qnil))
1065 f = sf;
1066 XSETFRAME (frame, f);
1068 else
1070 CHECK_FRAME (frame, 0);
1071 f = XFRAME (frame);
1074 if (! FRAME_LIVE_P (f))
1075 return Qnil;
1077 if (NILP (force) && !other_visible_frames (f))
1078 error ("Attempt to delete the sole visible or iconified frame");
1080 #if 0
1081 /* This is a nice idea, but x_connection_closed needs to be able
1082 to delete the last frame, if it is gone. */
1083 if (NILP (XCDR (Vframe_list)))
1084 error ("Attempt to delete the only frame");
1085 #endif
1087 /* Does this frame have a minibuffer, and is it the surrogate
1088 minibuffer for any other frame? */
1089 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1091 Lisp_Object frames;
1093 for (frames = Vframe_list;
1094 CONSP (frames);
1095 frames = XCDR (frames))
1097 Lisp_Object this;
1098 this = XCAR (frames);
1100 if (! EQ (this, frame)
1101 && EQ (frame,
1102 WINDOW_FRAME (XWINDOW
1103 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1104 error ("Attempt to delete a surrogate minibuffer frame");
1108 /* Run `delete-frame-hook'. */
1109 if (!NILP (Vrun_hooks))
1111 Lisp_Object args[2];
1112 args[0] = intern ("delete-frame-hook");
1113 args[1] = frame;
1114 Frun_hook_with_args (2, args);
1117 minibuffer_selected = EQ (minibuf_window, selected_window);
1119 /* Don't let the frame remain selected. */
1120 if (f == sf)
1122 Lisp_Object tail, frame1;
1124 /* Look for another visible frame on the same terminal. */
1125 frame1 = next_frame (frame, Qvisible);
1127 /* If there is none, find *some* other frame. */
1128 if (NILP (frame1) || EQ (frame1, frame))
1130 FOR_EACH_FRAME (tail, frame1)
1132 if (! EQ (frame, frame1))
1133 break;
1137 do_switch_frame (frame1, Qnil, 0);
1138 sf = SELECTED_FRAME ();
1141 /* Don't allow minibuf_window to remain on a deleted frame. */
1142 if (EQ (f->minibuffer_window, minibuf_window))
1144 Fset_window_buffer (sf->minibuffer_window,
1145 XWINDOW (minibuf_window)->buffer);
1146 minibuf_window = sf->minibuffer_window;
1148 /* If the dying minibuffer window was selected,
1149 select the new one. */
1150 if (minibuffer_selected)
1151 Fselect_window (minibuf_window);
1154 /* Don't let echo_area_window to remain on a deleted frame. */
1155 if (EQ (f->minibuffer_window, echo_area_window))
1156 echo_area_window = sf->minibuffer_window;
1158 /* Clear any X selections for this frame. */
1159 #ifdef HAVE_X_WINDOWS
1160 if (FRAME_X_P (f))
1161 x_clear_frame_selections (f);
1162 #endif
1164 /* Free glyphs.
1165 This function must be called before the window tree of the
1166 frame is deleted because windows contain dynamically allocated
1167 memory. */
1168 free_glyphs (f);
1170 /* Mark all the windows that used to be on FRAME as deleted, and then
1171 remove the reference to them. */
1172 delete_all_subwindows (XWINDOW (f->root_window));
1173 f->root_window = Qnil;
1175 Vframe_list = Fdelq (frame, Vframe_list);
1176 FRAME_SET_VISIBLE (f, 0);
1178 if (f->namebuf)
1179 xfree (f->namebuf);
1180 if (FRAME_INSERT_COST (f))
1181 xfree (FRAME_INSERT_COST (f));
1182 if (FRAME_DELETEN_COST (f))
1183 xfree (FRAME_DELETEN_COST (f));
1184 if (FRAME_INSERTN_COST (f))
1185 xfree (FRAME_INSERTN_COST (f));
1186 if (FRAME_DELETE_COST (f))
1187 xfree (FRAME_DELETE_COST (f));
1188 if (FRAME_MESSAGE_BUF (f))
1189 xfree (FRAME_MESSAGE_BUF (f));
1191 /* Since some events are handled at the interrupt level, we may get
1192 an event for f at any time; if we zero out the frame's display
1193 now, then we may trip up the event-handling code. Instead, we'll
1194 promise that the display of the frame must be valid until we have
1195 called the window-system-dependent frame destruction routine. */
1197 /* I think this should be done with a hook. */
1198 #ifdef HAVE_WINDOW_SYSTEM
1199 if (FRAME_WINDOW_P (f))
1200 x_destroy_window (f);
1201 #endif
1203 f->output_data.nothing = 0;
1205 /* If we've deleted the last_nonminibuf_frame, then try to find
1206 another one. */
1207 if (f == last_nonminibuf_frame)
1209 Lisp_Object frames;
1211 last_nonminibuf_frame = 0;
1213 for (frames = Vframe_list;
1214 CONSP (frames);
1215 frames = XCDR (frames))
1217 f = XFRAME (XCAR (frames));
1218 if (!FRAME_MINIBUF_ONLY_P (f))
1220 last_nonminibuf_frame = f;
1221 break;
1226 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1227 find another one. Prefer minibuffer-only frames, but also notice
1228 frames with other windows. */
1229 if (EQ (frame, FRAME_KBOARD (f)->Vdefault_minibuffer_frame))
1231 Lisp_Object frames;
1233 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1234 Lisp_Object frame_with_minibuf;
1235 /* Some frame we found on the same kboard, or nil if there are none. */
1236 Lisp_Object frame_on_same_kboard;
1238 frame_on_same_kboard = Qnil;
1239 frame_with_minibuf = Qnil;
1241 for (frames = Vframe_list;
1242 CONSP (frames);
1243 frames = XCDR (frames))
1245 Lisp_Object this;
1246 struct frame *f1;
1248 this = XCAR (frames);
1249 if (!FRAMEP (this))
1250 abort ();
1251 f1 = XFRAME (this);
1253 /* Consider only frames on the same kboard
1254 and only those with minibuffers. */
1255 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1)
1256 && FRAME_HAS_MINIBUF_P (f1))
1258 frame_with_minibuf = this;
1259 if (FRAME_MINIBUF_ONLY_P (f1))
1260 break;
1263 if (FRAME_KBOARD (f) == FRAME_KBOARD (f1))
1264 frame_on_same_kboard = this;
1267 if (!NILP (frame_on_same_kboard))
1269 /* We know that there must be some frame with a minibuffer out
1270 there. If this were not true, all of the frames present
1271 would have to be minibufferless, which implies that at some
1272 point their minibuffer frames must have been deleted, but
1273 that is prohibited at the top; you can't delete surrogate
1274 minibuffer frames. */
1275 if (NILP (frame_with_minibuf))
1276 abort ();
1278 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = frame_with_minibuf;
1280 else
1281 /* No frames left on this kboard--say no minibuffer either. */
1282 FRAME_KBOARD (f)->Vdefault_minibuffer_frame = Qnil;
1285 /* Cause frame titles to update--necessary if we now have just one frame. */
1286 update_mode_lines = 1;
1288 return Qnil;
1291 /* Return mouse position in character cell units. */
1293 DEFUN ("mouse-position", Fmouse_position, Smouse_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 character cells, 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.\n\
1300 Runs the abnormal hook `mouse-position-function' with the normal return\n\
1301 value as argument.")
1304 FRAME_PTR f;
1305 Lisp_Object lispy_dummy;
1306 enum scroll_bar_part party_dummy;
1307 Lisp_Object x, y, retval;
1308 int col, row;
1309 unsigned long long_dummy;
1310 struct gcpro gcpro1;
1312 f = SELECTED_FRAME ();
1313 x = y = Qnil;
1315 #ifdef HAVE_MOUSE
1316 /* It's okay for the hook to refrain from storing anything. */
1317 if (mouse_position_hook)
1318 (*mouse_position_hook) (&f, -1,
1319 &lispy_dummy, &party_dummy,
1320 &x, &y,
1321 &long_dummy);
1322 if (! NILP (x))
1324 col = XINT (x);
1325 row = XINT (y);
1326 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1327 XSETINT (x, col);
1328 XSETINT (y, row);
1330 #endif
1331 XSETFRAME (lispy_dummy, f);
1332 retval = Fcons (lispy_dummy, Fcons (x, y));
1333 GCPRO1 (retval);
1334 if (!NILP (Vmouse_position_function))
1335 retval = call1 (Vmouse_position_function, retval);
1336 RETURN_UNGCPRO (retval);
1339 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1340 Smouse_pixel_position, 0, 0, 0,
1341 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1342 The position is given in pixel units, where (0, 0) is the\n\
1343 upper-left corner.\n\
1344 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1345 to read the mouse position, it returns the selected frame for FRAME\n\
1346 and nil for X and Y.")
1349 FRAME_PTR f;
1350 Lisp_Object lispy_dummy;
1351 enum scroll_bar_part party_dummy;
1352 Lisp_Object x, y;
1353 unsigned long long_dummy;
1355 f = SELECTED_FRAME ();
1356 x = y = Qnil;
1358 #ifdef HAVE_MOUSE
1359 /* It's okay for the hook to refrain from storing anything. */
1360 if (mouse_position_hook)
1361 (*mouse_position_hook) (&f, -1,
1362 &lispy_dummy, &party_dummy,
1363 &x, &y,
1364 &long_dummy);
1365 #endif
1366 XSETFRAME (lispy_dummy, f);
1367 return Fcons (lispy_dummy, Fcons (x, y));
1370 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1371 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
1372 Coordinates are relative to the frame, not a window,\n\
1373 so the coordinates of the top left character in the frame\n\
1374 may be nonzero due to left-hand scroll bars or the menu bar.\n\
1376 This function is a no-op for an X frame that is not visible.\n\
1377 If you have just created a frame, you must wait for it to become visible\n\
1378 before calling this function on it, like this.\n\
1379 (while (not (frame-visible-p frame)) (sleep-for .5))")
1380 (frame, x, y)
1381 Lisp_Object frame, x, y;
1383 CHECK_LIVE_FRAME (frame, 0);
1384 CHECK_NUMBER (x, 2);
1385 CHECK_NUMBER (y, 1);
1387 /* I think this should be done with a hook. */
1388 #ifdef HAVE_WINDOW_SYSTEM
1389 if (FRAME_WINDOW_P (XFRAME (frame)))
1390 /* Warping the mouse will cause enternotify and focus events. */
1391 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1392 #else
1393 #if defined (MSDOS) && defined (HAVE_MOUSE)
1394 if (FRAME_MSDOS_P (XFRAME (frame)))
1396 Fselect_frame (frame, Qnil);
1397 mouse_moveto (XINT (x), XINT (y));
1399 #endif
1400 #endif
1402 return Qnil;
1405 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1406 Sset_mouse_pixel_position, 3, 3, 0,
1407 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1408 Note, this is a no-op for an X frame that is not visible.\n\
1409 If you have just created a frame, you must wait for it to become visible\n\
1410 before calling this function on it, like this.\n\
1411 (while (not (frame-visible-p frame)) (sleep-for .5))")
1412 (frame, x, y)
1413 Lisp_Object frame, x, y;
1415 CHECK_LIVE_FRAME (frame, 0);
1416 CHECK_NUMBER (x, 2);
1417 CHECK_NUMBER (y, 1);
1419 /* I think this should be done with a hook. */
1420 #ifdef HAVE_WINDOW_SYSTEM
1421 if (FRAME_WINDOW_P (XFRAME (frame)))
1422 /* Warping the mouse will cause enternotify and focus events. */
1423 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1424 #else
1425 #if defined (MSDOS) && defined (HAVE_MOUSE)
1426 if (FRAME_MSDOS_P (XFRAME (frame)))
1428 Fselect_frame (frame, Qnil);
1429 mouse_moveto (XINT (x), XINT (y));
1431 #endif
1432 #endif
1434 return Qnil;
1437 static void make_frame_visible_1 P_ ((Lisp_Object));
1439 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1440 0, 1, "",
1441 "Make the frame FRAME visible (assuming it is an X-window).\n\
1442 If omitted, FRAME defaults to the currently selected frame.")
1443 (frame)
1444 Lisp_Object frame;
1446 if (NILP (frame))
1447 frame = selected_frame;
1449 CHECK_LIVE_FRAME (frame, 0);
1451 /* I think this should be done with a hook. */
1452 #ifdef HAVE_WINDOW_SYSTEM
1453 if (FRAME_WINDOW_P (XFRAME (frame)))
1455 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1456 x_make_frame_visible (XFRAME (frame));
1458 #endif
1460 make_frame_visible_1 (XFRAME (frame)->root_window);
1462 /* Make menu bar update for the Buffers and Frams menus. */
1463 windows_or_buffers_changed++;
1465 return frame;
1468 /* Update the display_time slot of the buffers shown in WINDOW
1469 and all its descendents. */
1471 static void
1472 make_frame_visible_1 (window)
1473 Lisp_Object window;
1475 struct window *w;
1477 for (;!NILP (window); window = w->next)
1479 w = XWINDOW (window);
1481 if (!NILP (w->buffer))
1482 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1484 if (!NILP (w->vchild))
1485 make_frame_visible_1 (w->vchild);
1486 if (!NILP (w->hchild))
1487 make_frame_visible_1 (w->hchild);
1491 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1492 0, 2, "",
1493 "Make the frame FRAME invisible (assuming it is an X-window).\n\
1494 If omitted, FRAME defaults to the currently selected frame.\n\
1495 Normally you may not make FRAME invisible if all other frames are invisible,\n\
1496 but if the second optional argument FORCE is non-nil, you may do so.")
1497 (frame, force)
1498 Lisp_Object frame, force;
1500 if (NILP (frame))
1501 frame = selected_frame;
1503 CHECK_LIVE_FRAME (frame, 0);
1505 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1506 error ("Attempt to make invisible the sole visible or iconified frame");
1508 #if 0 /* This isn't logically necessary, and it can do GC. */
1509 /* Don't let the frame remain selected. */
1510 if (EQ (frame, selected_frame))
1511 do_switch_frame (next_frame (frame, Qt), Qnil, 0)
1512 #endif
1514 /* Don't allow minibuf_window to remain on a deleted frame. */
1515 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1517 struct frame *sf = XFRAME (selected_frame);
1518 Fset_window_buffer (sf->minibuffer_window,
1519 XWINDOW (minibuf_window)->buffer);
1520 minibuf_window = sf->minibuffer_window;
1523 /* I think this should be done with a hook. */
1524 #ifdef HAVE_WINDOW_SYSTEM
1525 if (FRAME_WINDOW_P (XFRAME (frame)))
1526 x_make_frame_invisible (XFRAME (frame));
1527 #endif
1529 /* Make menu bar update for the Buffers and Frams menus. */
1530 windows_or_buffers_changed++;
1532 return Qnil;
1535 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1536 0, 1, "",
1537 "Make the frame FRAME into an icon.\n\
1538 If omitted, FRAME defaults to the currently selected frame.")
1539 (frame)
1540 Lisp_Object frame;
1542 if (NILP (frame))
1543 frame = selected_frame;
1545 CHECK_LIVE_FRAME (frame, 0);
1547 #if 0 /* This isn't logically necessary, and it can do GC. */
1548 /* Don't let the frame remain selected. */
1549 if (EQ (frame, selected_frame))
1550 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
1551 #endif
1553 /* Don't allow minibuf_window to remain on a deleted frame. */
1554 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1556 struct frame *sf = XFRAME (selected_frame);
1557 Fset_window_buffer (sf->minibuffer_window,
1558 XWINDOW (minibuf_window)->buffer);
1559 minibuf_window = sf->minibuffer_window;
1562 /* I think this should be done with a hook. */
1563 #ifdef HAVE_WINDOW_SYSTEM
1564 if (FRAME_WINDOW_P (XFRAME (frame)))
1565 x_iconify_frame (XFRAME (frame));
1566 #endif
1568 /* Make menu bar update for the Buffers and Frams menus. */
1569 windows_or_buffers_changed++;
1571 return Qnil;
1574 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1575 1, 1, 0,
1576 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1577 A frame that is not \"visible\" is not updated and, if it works through\n\
1578 a window system, it may not show at all.\n\
1579 Return the symbol `icon' if frame is visible only as an icon.")
1580 (frame)
1581 Lisp_Object frame;
1583 CHECK_LIVE_FRAME (frame, 0);
1585 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1587 if (FRAME_VISIBLE_P (XFRAME (frame)))
1588 return Qt;
1589 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1590 return Qicon;
1591 return Qnil;
1594 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1595 0, 0, 0,
1596 "Return a list of all frames now \"visible\" (being updated).")
1599 Lisp_Object tail, frame;
1600 struct frame *f;
1601 Lisp_Object value;
1603 value = Qnil;
1604 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1606 frame = XCAR (tail);
1607 if (!FRAMEP (frame))
1608 continue;
1609 f = XFRAME (frame);
1610 if (FRAME_VISIBLE_P (f))
1611 value = Fcons (frame, value);
1613 return value;
1617 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
1618 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1619 If FRAME is invisible, make it visible.\n\
1620 If you don't specify a frame, the selected frame is used.\n\
1621 If Emacs is displaying on an ordinary terminal or some other device which\n\
1622 doesn't support multiple overlapping frames, this function does nothing.")
1623 (frame)
1624 Lisp_Object frame;
1626 if (NILP (frame))
1627 frame = selected_frame;
1629 CHECK_LIVE_FRAME (frame, 0);
1631 /* Do like the documentation says. */
1632 Fmake_frame_visible (frame);
1634 if (frame_raise_lower_hook)
1635 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1637 return Qnil;
1640 /* Should we have a corresponding function called Flower_Power? */
1641 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
1642 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1643 If you don't specify a frame, the selected frame is used.\n\
1644 If Emacs is displaying on an ordinary terminal or some other device which\n\
1645 doesn't support multiple overlapping frames, this function does nothing.")
1646 (frame)
1647 Lisp_Object frame;
1649 if (NILP (frame))
1650 frame = selected_frame;
1652 CHECK_LIVE_FRAME (frame, 0);
1654 if (frame_raise_lower_hook)
1655 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1657 return Qnil;
1661 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1662 1, 2, 0,
1663 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
1664 In other words, switch-frame events caused by events in FRAME will\n\
1665 request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1666 FOCUS-FRAME after reading an event typed at FRAME.\n\
1668 If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
1669 cancelled, and the frame again receives its own keystrokes.\n\
1671 Focus redirection is useful for temporarily redirecting keystrokes to\n\
1672 a surrogate minibuffer frame when a frame doesn't have its own\n\
1673 minibuffer window.\n\
1675 A frame's focus redirection can be changed by select-frame. If frame\n\
1676 FOO is selected, and then a different frame BAR is selected, any\n\
1677 frames redirecting their focus to FOO are shifted to redirect their\n\
1678 focus to BAR. This allows focus redirection to work properly when the\n\
1679 user switches from one frame to another using `select-window'.\n\
1681 This means that a frame whose focus is redirected to itself is treated\n\
1682 differently from a frame whose focus is redirected to nil; the former\n\
1683 is affected by select-frame, while the latter is not.\n\
1685 The redirection lasts until `redirect-frame-focus' is called to change it.")
1686 (frame, focus_frame)
1687 Lisp_Object frame, focus_frame;
1689 /* Note that we don't check for a live frame here. It's reasonable
1690 to redirect the focus of a frame you're about to delete, if you
1691 know what other frame should receive those keystrokes. */
1692 CHECK_FRAME (frame, 0);
1694 if (! NILP (focus_frame))
1695 CHECK_LIVE_FRAME (focus_frame, 1);
1697 XFRAME (frame)->focus_frame = focus_frame;
1699 if (frame_rehighlight_hook)
1700 (*frame_rehighlight_hook) (XFRAME (frame));
1702 return Qnil;
1706 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1707 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
1708 This returns nil if FRAME's focus is not redirected.\n\
1709 See `redirect-frame-focus'.")
1710 (frame)
1711 Lisp_Object frame;
1713 CHECK_LIVE_FRAME (frame, 0);
1715 return FRAME_FOCUS_FRAME (XFRAME (frame));
1720 /* Return the value of frame parameter PROP in frame FRAME. */
1722 Lisp_Object
1723 get_frame_param (frame, prop)
1724 register struct frame *frame;
1725 Lisp_Object prop;
1727 register Lisp_Object tem;
1729 tem = Fassq (prop, frame->param_alist);
1730 if (EQ (tem, Qnil))
1731 return tem;
1732 return Fcdr (tem);
1735 /* Return the buffer-predicate of the selected frame. */
1737 Lisp_Object
1738 frame_buffer_predicate (frame)
1739 Lisp_Object frame;
1741 return XFRAME (frame)->buffer_predicate;
1744 /* Return the buffer-list of the selected frame. */
1746 Lisp_Object
1747 frame_buffer_list (frame)
1748 Lisp_Object frame;
1750 return XFRAME (frame)->buffer_list;
1753 /* Set the buffer-list of the selected frame. */
1755 void
1756 set_frame_buffer_list (frame, list)
1757 Lisp_Object frame, list;
1759 XFRAME (frame)->buffer_list = list;
1762 /* Discard BUFFER from the buffer-list of each frame. */
1764 void
1765 frames_discard_buffer (buffer)
1766 Lisp_Object buffer;
1768 Lisp_Object frame, tail;
1770 FOR_EACH_FRAME (tail, frame)
1772 XFRAME (frame)->buffer_list
1773 = Fdelq (buffer, XFRAME (frame)->buffer_list);
1777 /* Move BUFFER to the end of the buffer-list of each frame. */
1779 void
1780 frames_bury_buffer (buffer)
1781 Lisp_Object buffer;
1783 Lisp_Object frame, tail;
1785 FOR_EACH_FRAME (tail, frame)
1787 struct frame *f = XFRAME (frame);
1788 Lisp_Object found;
1790 found = Fmemq (buffer, f->buffer_list);
1791 if (!NILP (found))
1792 f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),
1793 Fcons (buffer, Qnil));
1797 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1798 If the alist already has an element for PROP, we change it. */
1800 void
1801 store_in_alist (alistptr, prop, val)
1802 Lisp_Object *alistptr, val;
1803 Lisp_Object prop;
1805 register Lisp_Object tem;
1807 tem = Fassq (prop, *alistptr);
1808 if (EQ (tem, Qnil))
1809 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1810 else
1811 Fsetcdr (tem, val);
1814 static int
1815 frame_name_fnn_p (str, len)
1816 char *str;
1817 int len;
1819 if (len > 1 && str[0] == 'F')
1821 char *end_ptr;
1823 strtol (str + 1, &end_ptr, 10);
1825 if (end_ptr == str + len)
1826 return 1;
1828 return 0;
1831 /* Set the name of the terminal frame. Also used by MSDOS frames.
1832 Modeled after x_set_name which is used for WINDOW frames. */
1834 void
1835 set_term_frame_name (f, name)
1836 struct frame *f;
1837 Lisp_Object name;
1839 f->explicit_name = ! NILP (name);
1841 /* If NAME is nil, set the name to F<num>. */
1842 if (NILP (name))
1844 char namebuf[20];
1846 /* Check for no change needed in this very common case
1847 before we do any consing. */
1848 if (frame_name_fnn_p (XSTRING (f->name)->data,
1849 STRING_BYTES (XSTRING (f->name))))
1850 return;
1852 terminal_frame_count++;
1853 sprintf (namebuf, "F%d", terminal_frame_count);
1854 name = build_string (namebuf);
1856 else
1858 CHECK_STRING (name, 0);
1860 /* Don't change the name if it's already NAME. */
1861 if (! NILP (Fstring_equal (name, f->name)))
1862 return;
1864 /* Don't allow the user to set the frame name to F<num>, so it
1865 doesn't clash with the names we generate for terminal frames. */
1866 if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))
1867 error ("Frame names of the form F<num> are usurped by Emacs");
1870 f->name = name;
1871 update_mode_lines = 1;
1874 void
1875 store_frame_param (f, prop, val)
1876 struct frame *f;
1877 Lisp_Object prop, val;
1879 register Lisp_Object old_alist_elt;
1881 /* The buffer-alist parameter is stored in a special place and is
1882 not in the alist. */
1883 if (EQ (prop, Qbuffer_list))
1885 f->buffer_list = val;
1886 return;
1889 /* If PROP is a symbol which is supposed to have frame-local values,
1890 and it is set up based on this frame, switch to the global
1891 binding. That way, we can create or alter the frame-local binding
1892 without messing up the symbol's status. */
1893 if (SYMBOLP (prop))
1895 Lisp_Object valcontents;
1896 valcontents = XSYMBOL (prop)->value;
1897 if ((BUFFER_LOCAL_VALUEP (valcontents)
1898 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1899 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1900 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
1901 swap_in_global_binding (prop);
1904 /* Update the frame parameter alist. */
1905 old_alist_elt = Fassq (prop, f->param_alist);
1906 if (EQ (old_alist_elt, Qnil))
1907 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
1908 else
1909 Fsetcdr (old_alist_elt, val);
1911 /* Update some other special parameters in their special places
1912 in addition to the alist. */
1914 if (EQ (prop, Qbuffer_predicate))
1915 f->buffer_predicate = val;
1917 if (! FRAME_WINDOW_P (f))
1919 if (EQ (prop, Qmenu_bar_lines))
1920 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
1921 else if (EQ (prop, Qname))
1922 set_term_frame_name (f, val);
1925 if (EQ (prop, Qminibuffer) && WINDOWP (val))
1927 if (! MINI_WINDOW_P (XWINDOW (val)))
1928 error ("Surrogate minibuffer windows must be minibuffer windows.");
1930 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1931 && !EQ (val, f->minibuffer_window))
1932 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
1934 /* Install the chosen minibuffer window, with proper buffer. */
1935 f->minibuffer_window = val;
1939 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1940 "Return the parameters-alist of frame FRAME.\n\
1941 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
1942 The meaningful PARMs depend on the kind of frame.\n\
1943 If FRAME is omitted, return information on the currently selected frame.")
1944 (frame)
1945 Lisp_Object frame;
1947 Lisp_Object alist;
1948 FRAME_PTR f;
1949 int height, width;
1950 struct gcpro gcpro1;
1952 if (EQ (frame, Qnil))
1953 frame = selected_frame;
1955 CHECK_FRAME (frame, 0);
1956 f = XFRAME (frame);
1958 if (!FRAME_LIVE_P (f))
1959 return Qnil;
1961 alist = Fcopy_alist (f->param_alist);
1962 GCPRO1 (alist);
1964 if (!FRAME_WINDOW_P (f))
1966 int fg = FRAME_FOREGROUND_PIXEL (f);
1967 int bg = FRAME_BACKGROUND_PIXEL (f);
1968 Lisp_Object elt;
1970 /* If the frame's parameter alist says the colors are
1971 unspecified and reversed, take the frame's background pixel
1972 for foreground and vice versa. */
1973 elt = Fassq (Qforeground_color, alist);
1974 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
1976 if (strncmp (XSTRING (XCDR (elt))->data,
1977 unspecified_bg,
1978 XSTRING (XCDR (elt))->size) == 0)
1979 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
1980 else if (strncmp (XSTRING (XCDR (elt))->data,
1981 unspecified_fg,
1982 XSTRING (XCDR (elt))->size) == 0)
1983 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
1985 else
1986 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
1987 elt = Fassq (Qbackground_color, alist);
1988 if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
1990 if (strncmp (XSTRING (XCDR (elt))->data,
1991 unspecified_fg,
1992 XSTRING (XCDR (elt))->size) == 0)
1993 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
1994 else if (strncmp (XSTRING (XCDR (elt))->data,
1995 unspecified_bg,
1996 XSTRING (XCDR (elt))->size) == 0)
1997 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
1999 else
2000 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2001 store_in_alist (&alist, intern ("font"),
2002 build_string (FRAME_MSDOS_P (f)
2003 ? "ms-dos"
2004 : FRAME_W32_P (f) ? "w32term"
2005 :"tty"));
2007 store_in_alist (&alist, Qname, f->name);
2008 height = (FRAME_NEW_HEIGHT (f) ? FRAME_NEW_HEIGHT (f) : FRAME_HEIGHT (f));
2009 store_in_alist (&alist, Qheight, make_number (height));
2010 width = (FRAME_NEW_WIDTH (f) ? FRAME_NEW_WIDTH (f) : FRAME_WIDTH (f));
2011 store_in_alist (&alist, Qwidth, make_number (width));
2012 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2013 store_in_alist (&alist, Qminibuffer,
2014 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2015 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2016 : FRAME_MINIBUF_WINDOW (f)));
2017 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2018 store_in_alist (&alist, Qbuffer_list,
2019 frame_buffer_list (selected_frame));
2021 /* I think this should be done with a hook. */
2022 #ifdef HAVE_WINDOW_SYSTEM
2023 if (FRAME_WINDOW_P (f))
2024 x_report_frame_params (f, &alist);
2025 else
2026 #endif
2028 /* This ought to be correct in f->param_alist for an X frame. */
2029 Lisp_Object lines;
2030 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2031 store_in_alist (&alist, Qmenu_bar_lines, lines);
2034 UNGCPRO;
2035 return alist;
2039 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2040 "Return FRAME's value for parameter PARAMETER.\n\
2041 If FRAME is nil, describe the currently selected frame.")
2042 (frame, parameter)
2043 Lisp_Object frame, parameter;
2045 struct frame *f;
2046 Lisp_Object value;
2048 if (NILP (frame))
2049 frame = selected_frame;
2050 else
2051 CHECK_FRAME (frame, 0);
2052 CHECK_SYMBOL (parameter, 1);
2054 f = XFRAME (frame);
2055 value = Qnil;
2057 if (FRAME_LIVE_P (f))
2059 if (EQ (parameter, Qname))
2060 value = f->name;
2061 #ifdef HAVE_X_WINDOWS
2062 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2063 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2064 #endif /* HAVE_X_WINDOWS */
2065 else
2067 value = Fassq (parameter, f->param_alist);
2068 if (CONSP (value))
2070 value = XCDR (value);
2071 /* Fframe_parameters puts the actual fg/bg color names,
2072 even if f->param_alist says otherwise. This is
2073 important when param_alist's notion of colors is
2074 "unspecified". We need to do the same here. */
2075 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2077 char *color_name;
2078 EMACS_INT csz;
2080 if (EQ (parameter, Qbackground_color))
2082 color_name = XSTRING (value)->data;
2083 csz = XSTRING (value)->size;
2084 if (strncmp (color_name, unspecified_bg, csz) == 0)
2085 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2086 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2087 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2089 else if (EQ (parameter, Qforeground_color))
2091 color_name = XSTRING (value)->data;
2092 csz = XSTRING (value)->size;
2093 if (strncmp (color_name, unspecified_fg, csz) == 0)
2094 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2095 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2096 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2100 else if (EQ (parameter, Qdisplay_type)
2101 || EQ (parameter, Qbackground_mode))
2102 /* Avoid consing in frequent cases. */
2103 value = Qnil;
2104 else
2105 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2109 return value;
2113 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2114 Smodify_frame_parameters, 2, 2, 0,
2115 "Modify the parameters of frame FRAME according to ALIST.\n\
2116 ALIST is an alist of parameters to change and their new values.\n\
2117 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
2118 The meaningful PARMs depend on the kind of frame.\n\
2119 Undefined PARMs are ignored, but stored in the frame's parameter list\n\
2120 so that `frame-parameters' will return them.\n\
2122 The value of frame parameter FOO can also be accessed\n\
2123 as a frame-local binding for the variable FOO, if you have\n\
2124 enabled such bindings for that variable with `make-variable-frame-local'.")
2125 (frame, alist)
2126 Lisp_Object frame, alist;
2128 FRAME_PTR f;
2129 register Lisp_Object tail, prop, val;
2130 int count = BINDING_STACK_SIZE ();
2132 /* Bind this to t to inhibit initialization of the default face from
2133 X resources in face-set-after-frame-default. If we don't inhibit
2134 this, modifying the `font' frame parameter, for example, while
2135 there is a `default.attributeFont' X resource, won't work,
2136 because `default's font is reset to the value of the X resource
2137 and that resets the `font' frame parameter. */
2138 specbind (Qinhibit_default_face_x_resources, Qt);
2140 if (EQ (frame, Qnil))
2141 frame = selected_frame;
2142 CHECK_LIVE_FRAME (frame, 0);
2143 f = XFRAME (frame);
2145 /* I think this should be done with a hook. */
2146 #ifdef HAVE_WINDOW_SYSTEM
2147 if (FRAME_WINDOW_P (f))
2148 x_set_frame_parameters (f, alist);
2149 else
2150 #endif
2151 #ifdef MSDOS
2152 if (FRAME_MSDOS_P (f))
2153 IT_set_frame_parameters (f, alist);
2154 else
2155 #endif
2158 int length = XINT (Flength (alist));
2159 int i;
2160 Lisp_Object *parms
2161 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2162 Lisp_Object *values
2163 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2165 /* Extract parm names and values into those vectors. */
2167 i = 0;
2168 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2170 Lisp_Object elt;
2172 elt = Fcar (tail);
2173 parms[i] = Fcar (elt);
2174 values[i] = Fcdr (elt);
2175 i++;
2178 /* Now process them in reverse of specified order. */
2179 for (i--; i >= 0; i--)
2181 prop = parms[i];
2182 val = values[i];
2183 store_frame_param (f, prop, val);
2187 return unbind_to (count, Qnil);
2190 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2191 0, 1, 0,
2192 "Height in pixels of a line in the font in frame FRAME.\n\
2193 If FRAME is omitted, the selected frame is used.\n\
2194 For a terminal frame, the value is always 1.")
2195 (frame)
2196 Lisp_Object frame;
2198 struct frame *f;
2200 if (NILP (frame))
2201 frame = selected_frame;
2202 CHECK_FRAME (frame, 0);
2203 f = XFRAME (frame);
2205 #ifdef HAVE_WINDOW_SYSTEM
2206 if (FRAME_WINDOW_P (f))
2207 return make_number (x_char_height (f));
2208 else
2209 #endif
2210 return make_number (1);
2214 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2215 0, 1, 0,
2216 "Width in pixels of characters in the font in frame FRAME.\n\
2217 If FRAME is omitted, the selected frame is used.\n\
2218 The width is the same for all characters, because\n\
2219 currently Emacs supports only fixed-width fonts.\n\
2220 For a terminal screen, the value is always 1.")
2221 (frame)
2222 Lisp_Object frame;
2224 struct frame *f;
2226 if (NILP (frame))
2227 frame = selected_frame;
2228 CHECK_FRAME (frame, 0);
2229 f = XFRAME (frame);
2231 #ifdef HAVE_WINDOW_SYSTEM
2232 if (FRAME_WINDOW_P (f))
2233 return make_number (x_char_width (f));
2234 else
2235 #endif
2236 return make_number (1);
2239 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2240 Sframe_pixel_height, 0, 1, 0,
2241 "Return a FRAME's height in pixels.\n\
2242 This counts only the height available for text lines,\n\
2243 not menu bars on window-system Emacs frames.\n\
2244 For a terminal frame, the result really gives the height in characters.\n\
2245 If FRAME is omitted, the selected frame is used.")
2246 (frame)
2247 Lisp_Object frame;
2249 struct frame *f;
2251 if (NILP (frame))
2252 frame = selected_frame;
2253 CHECK_FRAME (frame, 0);
2254 f = XFRAME (frame);
2256 #ifdef HAVE_WINDOW_SYSTEM
2257 if (FRAME_WINDOW_P (f))
2258 return make_number (x_pixel_height (f));
2259 else
2260 #endif
2261 return make_number (FRAME_HEIGHT (f));
2264 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2265 Sframe_pixel_width, 0, 1, 0,
2266 "Return FRAME's width in pixels.\n\
2267 For a terminal frame, the result really gives the width in characters.\n\
2268 If FRAME is omitted, the selected frame is used.")
2269 (frame)
2270 Lisp_Object frame;
2272 struct frame *f;
2274 if (NILP (frame))
2275 frame = selected_frame;
2276 CHECK_FRAME (frame, 0);
2277 f = XFRAME (frame);
2279 #ifdef HAVE_WINDOW_SYSTEM
2280 if (FRAME_WINDOW_P (f))
2281 return make_number (x_pixel_width (f));
2282 else
2283 #endif
2284 return make_number (FRAME_WIDTH (f));
2287 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2288 "Specify that the frame FRAME has LINES lines.\n\
2289 Optional third arg non-nil means that redisplay should use LINES lines\n\
2290 but that the idea of the actual height of the frame should not be changed.")
2291 (frame, lines, pretend)
2292 Lisp_Object frame, lines, pretend;
2294 register struct frame *f;
2296 CHECK_NUMBER (lines, 0);
2297 if (NILP (frame))
2298 frame = selected_frame;
2299 CHECK_LIVE_FRAME (frame, 0);
2300 f = XFRAME (frame);
2302 /* I think this should be done with a hook. */
2303 #ifdef HAVE_WINDOW_SYSTEM
2304 if (FRAME_WINDOW_P (f))
2306 if (XINT (lines) != f->height)
2307 x_set_window_size (f, 1, f->width, XINT (lines));
2308 do_pending_window_change (0);
2310 else
2311 #endif
2312 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2313 return Qnil;
2316 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2317 "Specify that the frame FRAME has COLS columns.\n\
2318 Optional third arg non-nil means that redisplay should use COLS columns\n\
2319 but that the idea of the actual width of the frame should not be changed.")
2320 (frame, cols, pretend)
2321 Lisp_Object frame, cols, pretend;
2323 register struct frame *f;
2324 CHECK_NUMBER (cols, 0);
2325 if (NILP (frame))
2326 frame = selected_frame;
2327 CHECK_LIVE_FRAME (frame, 0);
2328 f = XFRAME (frame);
2330 /* I think this should be done with a hook. */
2331 #ifdef HAVE_WINDOW_SYSTEM
2332 if (FRAME_WINDOW_P (f))
2334 if (XINT (cols) != f->width)
2335 x_set_window_size (f, 1, XINT (cols), f->height);
2336 do_pending_window_change (0);
2338 else
2339 #endif
2340 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2341 return Qnil;
2344 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2345 "Sets size of FRAME to COLS by ROWS, measured in characters.")
2346 (frame, cols, rows)
2347 Lisp_Object frame, cols, rows;
2349 register struct frame *f;
2351 CHECK_LIVE_FRAME (frame, 0);
2352 CHECK_NUMBER (cols, 2);
2353 CHECK_NUMBER (rows, 1);
2354 f = XFRAME (frame);
2356 /* I think this should be done with a hook. */
2357 #ifdef HAVE_WINDOW_SYSTEM
2358 if (FRAME_WINDOW_P (f))
2360 if (XINT (rows) != f->height || XINT (cols) != f->width
2361 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2362 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2363 do_pending_window_change (0);
2365 else
2366 #endif
2367 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2369 return Qnil;
2372 DEFUN ("set-frame-position", Fset_frame_position,
2373 Sset_frame_position, 3, 3, 0,
2374 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
2375 This is actually the position of the upper left corner of the frame.\n\
2376 Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
2377 the rightmost or bottommost possible position (that stays within the screen).")
2378 (frame, xoffset, yoffset)
2379 Lisp_Object frame, xoffset, yoffset;
2381 register struct frame *f;
2383 CHECK_LIVE_FRAME (frame, 0);
2384 CHECK_NUMBER (xoffset, 1);
2385 CHECK_NUMBER (yoffset, 2);
2386 f = XFRAME (frame);
2388 /* I think this should be done with a hook. */
2389 #ifdef HAVE_WINDOW_SYSTEM
2390 if (FRAME_WINDOW_P (f))
2391 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2392 #endif
2394 return Qt;
2398 void
2399 syms_of_frame ()
2401 Qframep = intern ("framep");
2402 staticpro (&Qframep);
2403 Qframe_live_p = intern ("frame-live-p");
2404 staticpro (&Qframe_live_p);
2405 Qheight = intern ("height");
2406 staticpro (&Qheight);
2407 Qicon = intern ("icon");
2408 staticpro (&Qicon);
2409 Qminibuffer = intern ("minibuffer");
2410 staticpro (&Qminibuffer);
2411 Qmodeline = intern ("modeline");
2412 staticpro (&Qmodeline);
2413 Qname = intern ("name");
2414 staticpro (&Qname);
2415 Qonly = intern ("only");
2416 staticpro (&Qonly);
2417 Qunsplittable = intern ("unsplittable");
2418 staticpro (&Qunsplittable);
2419 Qmenu_bar_lines = intern ("menu-bar-lines");
2420 staticpro (&Qmenu_bar_lines);
2421 Qtool_bar_lines = intern ("tool-bar-lines");
2422 staticpro (&Qtool_bar_lines);
2423 Qwidth = intern ("width");
2424 staticpro (&Qwidth);
2425 Qx = intern ("x");
2426 staticpro (&Qx);
2427 Qw32 = intern ("w32");
2428 staticpro (&Qw32);
2429 Qpc = intern ("pc");
2430 staticpro (&Qpc);
2431 Qmac = intern ("mac");
2432 staticpro (&Qmac);
2433 Qvisible = intern ("visible");
2434 staticpro (&Qvisible);
2435 Qbuffer_predicate = intern ("buffer-predicate");
2436 staticpro (&Qbuffer_predicate);
2437 Qbuffer_list = intern ("buffer-list");
2438 staticpro (&Qbuffer_list);
2439 Qtitle = intern ("title");
2440 staticpro (&Qtitle);
2441 Qdisplay_type = intern ("display-type");
2442 staticpro (&Qdisplay_type);
2443 Qbackground_mode = intern ("background-mode");
2444 staticpro (&Qbackground_mode);
2446 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
2447 "Alist of default values for frame creation.\n\
2448 These may be set in your init file, like this:\n\
2449 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
2450 These override values given in window system configuration data,\n\
2451 including X Windows' defaults database.\n\
2452 For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
2453 For values specific to the separate minibuffer frame, see\n\
2454 `minibuffer-frame-alist'.\n\
2455 The `menu-bar-lines' element of the list controls whether new frames\n\
2456 have menu bars; `menu-bar-mode' works by altering this element.");
2457 Vdefault_frame_alist = Qnil;
2459 Qinhibit_default_face_x_resources
2460 = intern ("inhibit-default-face-x-resources");
2461 staticpro (&Qinhibit_default_face_x_resources);
2463 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2464 "The initial frame-object, which represents Emacs's stdout.");
2466 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
2467 "Non-nil if all of emacs is iconified and frame updates are not needed.");
2468 Vemacs_iconified = Qnil;
2470 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
2471 "If non-nil, function applied to the normal result of `mouse-position'.\n\
2472 This abnormal hook exists for the benefit of packages like XTerm-mouse\n\
2473 which need to do mouse handling at the Lisp level.");
2474 Vmouse_position_function = Qnil;
2476 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
2477 "Minibufferless frames use this frame's minibuffer.\n\
2479 Emacs cannot create minibufferless frames unless this is set to an\n\
2480 appropriate surrogate.\n\
2482 Emacs consults this variable only when creating minibufferless\n\
2483 frames; once the frame is created, it sticks with its assigned\n\
2484 minibuffer, no matter what this variable is set to. This means that\n\
2485 this variable doesn't necessarily say anything meaningful about the\n\
2486 current set of frames, or where the minibuffer is currently being\n\
2487 displayed.");
2489 staticpro (&Vframe_list);
2491 defsubr (&Sactive_minibuffer_window);
2492 defsubr (&Sframep);
2493 defsubr (&Sframe_live_p);
2494 defsubr (&Smake_terminal_frame);
2495 defsubr (&Shandle_switch_frame);
2496 defsubr (&Signore_event);
2497 defsubr (&Sselect_frame);
2498 defsubr (&Sselected_frame);
2499 defsubr (&Swindow_frame);
2500 defsubr (&Sframe_root_window);
2501 defsubr (&Sframe_first_window);
2502 defsubr (&Sframe_selected_window);
2503 defsubr (&Sset_frame_selected_window);
2504 defsubr (&Sframe_list);
2505 defsubr (&Snext_frame);
2506 defsubr (&Sprevious_frame);
2507 defsubr (&Sdelete_frame);
2508 defsubr (&Smouse_position);
2509 defsubr (&Smouse_pixel_position);
2510 defsubr (&Sset_mouse_position);
2511 defsubr (&Sset_mouse_pixel_position);
2512 #if 0
2513 defsubr (&Sframe_configuration);
2514 defsubr (&Srestore_frame_configuration);
2515 #endif
2516 defsubr (&Smake_frame_visible);
2517 defsubr (&Smake_frame_invisible);
2518 defsubr (&Siconify_frame);
2519 defsubr (&Sframe_visible_p);
2520 defsubr (&Svisible_frame_list);
2521 defsubr (&Sraise_frame);
2522 defsubr (&Slower_frame);
2523 defsubr (&Sredirect_frame_focus);
2524 defsubr (&Sframe_focus);
2525 defsubr (&Sframe_parameters);
2526 defsubr (&Sframe_parameter);
2527 defsubr (&Smodify_frame_parameters);
2528 defsubr (&Sframe_char_height);
2529 defsubr (&Sframe_char_width);
2530 defsubr (&Sframe_pixel_height);
2531 defsubr (&Sframe_pixel_width);
2532 defsubr (&Sset_frame_height);
2533 defsubr (&Sset_frame_width);
2534 defsubr (&Sset_frame_size);
2535 defsubr (&Sset_frame_position);
2538 void
2539 keys_of_frame ()
2541 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2542 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
2543 initial_define_lispy_key (global_map, "iconify-frame", "ignore-event");
2544 initial_define_lispy_key (global_map, "make-frame-visible", "ignore-event");